// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Code generated by sidekick. DO NOT EDIT.

#![allow(rustdoc::redundant_explicit_links)]
#![allow(rustdoc::broken_intra_doc_links)]

mod debug;
mod deserialize;
mod serialize;

/// The result of a single bucket from a Firestore aggregation query.
///
/// The keys of `aggregate_fields` are the same for all results in an aggregation
/// query, unlike document queries which can have different fields present for
/// each result.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct AggregationResult {
    /// The result of the aggregation functions, ex: `COUNT(*) AS total_docs`.
    ///
    /// The key is the
    /// [alias][google.firestore.v1.StructuredAggregationQuery.Aggregation.alias]
    /// assigned to the aggregation function on input and the size of this map
    /// equals the number of aggregation functions in the query.
    ///
    /// [google.firestore.v1.StructuredAggregationQuery.Aggregation.alias]: crate::model::structured_aggregation_query::Aggregation::alias
    pub aggregate_fields: std::collections::HashMap<std::string::String, crate::model::Value>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl AggregationResult {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [aggregate_fields][crate::model::AggregationResult::aggregate_fields].
    pub fn set_aggregate_fields<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<crate::model::Value>,
    {
        use std::iter::Iterator;
        self.aggregate_fields = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }
}

impl wkt::message::Message for AggregationResult {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.AggregationResult"
    }
}

/// A sequence of bits, encoded in a byte array.
///
/// Each byte in the `bitmap` byte array stores 8 bits of the sequence. The only
/// exception is the last byte, which may store 8 _or fewer_ bits. The `padding`
/// defines the number of bits of the last byte to be ignored as "padding". The
/// values of these "padding" bits are unspecified and must be ignored.
///
/// To retrieve the first bit, bit 0, calculate: `(bitmap[0] & 0x01) != 0`.
/// To retrieve the second bit, bit 1, calculate: `(bitmap[0] & 0x02) != 0`.
/// To retrieve the third bit, bit 2, calculate: `(bitmap[0] & 0x04) != 0`.
/// To retrieve the fourth bit, bit 3, calculate: `(bitmap[0] & 0x08) != 0`.
/// To retrieve bit n, calculate: `(bitmap[n / 8] & (0x01 << (n % 8))) != 0`.
///
/// The "size" of a `BitSequence` (the number of bits it contains) is calculated
/// by this formula: `(bitmap.length * 8) - padding`.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct BitSequence {
    /// The bytes that encode the bit sequence.
    /// May have a length of zero.
    pub bitmap: ::bytes::Bytes,

    /// The number of bits of the last byte in `bitmap` to ignore as "padding".
    /// If the length of `bitmap` is zero, then this value must be `0`.
    /// Otherwise, this value must be between 0 and 7, inclusive.
    pub padding: i32,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl BitSequence {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [bitmap][crate::model::BitSequence::bitmap].
    pub fn set_bitmap<T: std::convert::Into<::bytes::Bytes>>(mut self, v: T) -> Self {
        self.bitmap = v.into();
        self
    }

    /// Sets the value of [padding][crate::model::BitSequence::padding].
    pub fn set_padding<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.padding = v.into();
        self
    }
}

impl wkt::message::Message for BitSequence {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.BitSequence"
    }
}

/// A bloom filter (<https://en.wikipedia.org/wiki/Bloom_filter>).
///
/// The bloom filter hashes the entries with MD5 and treats the resulting 128-bit
/// hash as 2 distinct 64-bit hash values, interpreted as unsigned integers
/// using 2's complement encoding.
///
/// These two hash values, named `h1` and `h2`, are then used to compute the
/// `hash_count` hash values using the formula, starting at `i=0`:
///
/// ```norust
/// h(i) = h1 + (i * h2)
/// ```
///
/// These resulting values are then taken modulo the number of bits in the bloom
/// filter to get the bits of the bloom filter to test for the given entry.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct BloomFilter {
    /// The bloom filter data.
    pub bits: std::option::Option<crate::model::BitSequence>,

    /// The number of hashes used by the algorithm.
    pub hash_count: i32,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl BloomFilter {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [bits][crate::model::BloomFilter::bits].
    pub fn set_bits<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::BitSequence>,
    {
        self.bits = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [bits][crate::model::BloomFilter::bits].
    pub fn set_or_clear_bits<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::BitSequence>,
    {
        self.bits = v.map(|x| x.into());
        self
    }

    /// Sets the value of [hash_count][crate::model::BloomFilter::hash_count].
    pub fn set_hash_count<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.hash_count = v.into();
        self
    }
}

impl wkt::message::Message for BloomFilter {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.BloomFilter"
    }
}

/// A set of field paths on a document.
/// Used to restrict a get or update operation on a document to a subset of its
/// fields.
/// This is different from standard field masks, as this is always scoped to a
/// [Document][google.firestore.v1.Document], and takes in account the dynamic
/// nature of [Value][google.firestore.v1.Value].
///
/// [google.firestore.v1.Document]: crate::model::Document
/// [google.firestore.v1.Value]: crate::model::Value
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct DocumentMask {
    /// The list of field paths in the mask. See
    /// [Document.fields][google.firestore.v1.Document.fields] for a field path
    /// syntax reference.
    ///
    /// [google.firestore.v1.Document.fields]: crate::model::Document::fields
    pub field_paths: std::vec::Vec<std::string::String>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl DocumentMask {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [field_paths][crate::model::DocumentMask::field_paths].
    pub fn set_field_paths<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.field_paths = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for DocumentMask {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.DocumentMask"
    }
}

/// A precondition on a document, used for conditional operations.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Precondition {
    /// The type of precondition.
    pub condition_type: std::option::Option<crate::model::precondition::ConditionType>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Precondition {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [condition_type][crate::model::Precondition::condition_type].
    ///
    /// Note that all the setters affecting `condition_type` are mutually
    /// exclusive.
    pub fn set_condition_type<
        T: std::convert::Into<std::option::Option<crate::model::precondition::ConditionType>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.condition_type = v.into();
        self
    }

    /// The value of [condition_type][crate::model::Precondition::condition_type]
    /// if it holds a `Exists`, `None` if the field is not set or
    /// holds a different branch.
    pub fn exists(&self) -> std::option::Option<&bool> {
        #[allow(unreachable_patterns)]
        self.condition_type.as_ref().and_then(|v| match v {
            crate::model::precondition::ConditionType::Exists(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [condition_type][crate::model::Precondition::condition_type]
    /// to hold a `Exists`.
    ///
    /// Note that all the setters affecting `condition_type` are
    /// mutually exclusive.
    pub fn set_exists<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.condition_type =
            std::option::Option::Some(crate::model::precondition::ConditionType::Exists(v.into()));
        self
    }

    /// The value of [condition_type][crate::model::Precondition::condition_type]
    /// if it holds a `UpdateTime`, `None` if the field is not set or
    /// holds a different branch.
    pub fn update_time(&self) -> std::option::Option<&std::boxed::Box<wkt::Timestamp>> {
        #[allow(unreachable_patterns)]
        self.condition_type.as_ref().and_then(|v| match v {
            crate::model::precondition::ConditionType::UpdateTime(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [condition_type][crate::model::Precondition::condition_type]
    /// to hold a `UpdateTime`.
    ///
    /// Note that all the setters affecting `condition_type` are
    /// mutually exclusive.
    pub fn set_update_time<T: std::convert::Into<std::boxed::Box<wkt::Timestamp>>>(
        mut self,
        v: T,
    ) -> Self {
        self.condition_type = std::option::Option::Some(
            crate::model::precondition::ConditionType::UpdateTime(v.into()),
        );
        self
    }
}

impl wkt::message::Message for Precondition {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.Precondition"
    }
}

/// Defines additional types related to [Precondition].
pub mod precondition {
    #[allow(unused_imports)]
    use super::*;

    /// The type of precondition.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum ConditionType {
        /// When set to `true`, the target document must exist.
        /// When set to `false`, the target document must not exist.
        Exists(bool),
        /// When set, the target document must exist and have been last updated at
        /// that time. Timestamp must be microsecond aligned.
        UpdateTime(std::boxed::Box<wkt::Timestamp>),
    }

    impl ConditionType {
        /// Initializes the enum to the [Exists](Self::Exists) branch.
        pub fn from_exists(value: impl std::convert::Into<bool>) -> Self {
            Self::Exists(value.into())
        }
        /// Initializes the enum to the [UpdateTime](Self::UpdateTime) branch.
        pub fn from_update_time(
            value: impl std::convert::Into<std::boxed::Box<wkt::Timestamp>>,
        ) -> Self {
            Self::UpdateTime(value.into())
        }
    }
}

/// Options for creating a new transaction.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct TransactionOptions {
    /// The mode of the transaction.
    pub mode: std::option::Option<crate::model::transaction_options::Mode>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl TransactionOptions {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [mode][crate::model::TransactionOptions::mode].
    ///
    /// Note that all the setters affecting `mode` are mutually
    /// exclusive.
    pub fn set_mode<
        T: std::convert::Into<std::option::Option<crate::model::transaction_options::Mode>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.mode = v.into();
        self
    }

    /// The value of [mode][crate::model::TransactionOptions::mode]
    /// if it holds a `ReadOnly`, `None` if the field is not set or
    /// holds a different branch.
    pub fn read_only(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::transaction_options::ReadOnly>> {
        #[allow(unreachable_patterns)]
        self.mode.as_ref().and_then(|v| match v {
            crate::model::transaction_options::Mode::ReadOnly(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [mode][crate::model::TransactionOptions::mode]
    /// to hold a `ReadOnly`.
    ///
    /// Note that all the setters affecting `mode` are
    /// mutually exclusive.
    pub fn set_read_only<
        T: std::convert::Into<std::boxed::Box<crate::model::transaction_options::ReadOnly>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.mode =
            std::option::Option::Some(crate::model::transaction_options::Mode::ReadOnly(v.into()));
        self
    }

    /// The value of [mode][crate::model::TransactionOptions::mode]
    /// if it holds a `ReadWrite`, `None` if the field is not set or
    /// holds a different branch.
    pub fn read_write(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::transaction_options::ReadWrite>> {
        #[allow(unreachable_patterns)]
        self.mode.as_ref().and_then(|v| match v {
            crate::model::transaction_options::Mode::ReadWrite(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [mode][crate::model::TransactionOptions::mode]
    /// to hold a `ReadWrite`.
    ///
    /// Note that all the setters affecting `mode` are
    /// mutually exclusive.
    pub fn set_read_write<
        T: std::convert::Into<std::boxed::Box<crate::model::transaction_options::ReadWrite>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.mode =
            std::option::Option::Some(crate::model::transaction_options::Mode::ReadWrite(v.into()));
        self
    }
}

impl wkt::message::Message for TransactionOptions {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.TransactionOptions"
    }
}

/// Defines additional types related to [TransactionOptions].
pub mod transaction_options {
    #[allow(unused_imports)]
    use super::*;

    /// Options for a transaction that can be used to read and write documents.
    ///
    /// Firestore does not allow 3rd party auth requests to create read-write.
    /// transactions.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct ReadWrite {
        /// An optional transaction to retry.
        pub retry_transaction: ::bytes::Bytes,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl ReadWrite {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [retry_transaction][crate::model::transaction_options::ReadWrite::retry_transaction].
        pub fn set_retry_transaction<T: std::convert::Into<::bytes::Bytes>>(
            mut self,
            v: T,
        ) -> Self {
            self.retry_transaction = v.into();
            self
        }
    }

    impl wkt::message::Message for ReadWrite {
        fn typename() -> &'static str {
            "type.googleapis.com/google.firestore.v1.TransactionOptions.ReadWrite"
        }
    }

    /// Options for a transaction that can only be used to read documents.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct ReadOnly {
        /// The consistency mode for this transaction. If not set, defaults to strong
        /// consistency.
        pub consistency_selector:
            std::option::Option<crate::model::transaction_options::read_only::ConsistencySelector>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl ReadOnly {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [consistency_selector][crate::model::transaction_options::ReadOnly::consistency_selector].
        ///
        /// Note that all the setters affecting `consistency_selector` are mutually
        /// exclusive.
        pub fn set_consistency_selector<
            T: std::convert::Into<
                    std::option::Option<
                        crate::model::transaction_options::read_only::ConsistencySelector,
                    >,
                >,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.consistency_selector = v.into();
            self
        }

        /// The value of [consistency_selector][crate::model::transaction_options::ReadOnly::consistency_selector]
        /// if it holds a `ReadTime`, `None` if the field is not set or
        /// holds a different branch.
        pub fn read_time(&self) -> std::option::Option<&std::boxed::Box<wkt::Timestamp>> {
            #[allow(unreachable_patterns)]
            self.consistency_selector.as_ref().and_then(|v| match v {
                crate::model::transaction_options::read_only::ConsistencySelector::ReadTime(v) => {
                    std::option::Option::Some(v)
                }
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [consistency_selector][crate::model::transaction_options::ReadOnly::consistency_selector]
        /// to hold a `ReadTime`.
        ///
        /// Note that all the setters affecting `consistency_selector` are
        /// mutually exclusive.
        pub fn set_read_time<T: std::convert::Into<std::boxed::Box<wkt::Timestamp>>>(
            mut self,
            v: T,
        ) -> Self {
            self.consistency_selector = std::option::Option::Some(
                crate::model::transaction_options::read_only::ConsistencySelector::ReadTime(
                    v.into(),
                ),
            );
            self
        }
    }

    impl wkt::message::Message for ReadOnly {
        fn typename() -> &'static str {
            "type.googleapis.com/google.firestore.v1.TransactionOptions.ReadOnly"
        }
    }

    /// Defines additional types related to [ReadOnly].
    pub mod read_only {
        #[allow(unused_imports)]
        use super::*;

        /// The consistency mode for this transaction. If not set, defaults to strong
        /// consistency.
        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum ConsistencySelector {
            /// Reads documents at the given time.
            ///
            /// This must be a microsecond precision timestamp within the past one
            /// hour, or if Point-in-Time Recovery is enabled, can additionally be a
            /// whole minute timestamp within the past 7 days.
            ReadTime(std::boxed::Box<wkt::Timestamp>),
        }

        impl ConsistencySelector {
            /// Initializes the enum to the [ReadTime](Self::ReadTime) branch.
            pub fn from_read_time(
                value: impl std::convert::Into<std::boxed::Box<wkt::Timestamp>>,
            ) -> Self {
                Self::ReadTime(value.into())
            }
        }
    }

    /// The mode of the transaction.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Mode {
        /// The transaction can only be used for read operations.
        ReadOnly(std::boxed::Box<crate::model::transaction_options::ReadOnly>),
        /// The transaction can be used for both read and write operations.
        ReadWrite(std::boxed::Box<crate::model::transaction_options::ReadWrite>),
    }

    impl Mode {
        /// Initializes the enum to the [ReadOnly](Self::ReadOnly) branch.
        pub fn from_read_only(
            value: impl std::convert::Into<std::boxed::Box<crate::model::transaction_options::ReadOnly>>,
        ) -> Self {
            Self::ReadOnly(value.into())
        }
        /// Initializes the enum to the [ReadWrite](Self::ReadWrite) branch.
        pub fn from_read_write(
            value: impl std::convert::Into<
                std::boxed::Box<crate::model::transaction_options::ReadWrite>,
            >,
        ) -> Self {
            Self::ReadWrite(value.into())
        }
    }
}

/// A Firestore document.
///
/// Must not exceed 1 MiB - 4 bytes.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Document {
    /// The resource name of the document, for example
    /// `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
    pub name: std::string::String,

    /// The document's fields.
    ///
    /// The map keys represent field names.
    ///
    /// Field names matching the regular expression `__.*__` are reserved. Reserved
    /// field names are forbidden except in certain documented contexts. The field
    /// names, represented as UTF-8, must not exceed 1,500 bytes and cannot be
    /// empty.
    ///
    /// Field paths may be used in other contexts to refer to structured fields
    /// defined here. For `map_value`, the field path is represented by a
    /// dot-delimited (`.`) string of segments. Each segment is either a simple
    /// field name (defined below) or a quoted field name. For example, the
    /// structured field `"foo" : { map_value: { "x&y" : { string_value: "hello"
    /// }}}` would be represented by the field path `` foo.`x&y` ``.
    ///
    /// A simple field name contains only characters `a` to `z`, `A` to `Z`,
    /// `0` to `9`, or `_`, and must not start with `0` to `9`. For example,
    /// `foo_bar_17`.
    ///
    /// A quoted field name starts and ends with `` ` `` and
    /// may contain any character. Some characters, including `` ` ``, must be
    /// escaped using a `\`. For example, `` `x&y` `` represents `x&y` and
    /// `` `bak\`tik` `` represents `` bak`tik ``.
    pub fields: std::collections::HashMap<std::string::String, crate::model::Value>,

    /// Output only. The time at which the document was created.
    ///
    /// This value increases monotonically when a document is deleted then
    /// recreated. It can also be compared to values from other documents and
    /// the `read_time` of a query.
    pub create_time: std::option::Option<wkt::Timestamp>,

    /// Output only. The time at which the document was last changed.
    ///
    /// This value is initially set to the `create_time` then increases
    /// monotonically with each change to the document. It can also be
    /// compared to values from other documents and the `read_time` of a query.
    pub update_time: std::option::Option<wkt::Timestamp>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Document {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::Document::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }

    /// Sets the value of [fields][crate::model::Document::fields].
    pub fn set_fields<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<crate::model::Value>,
    {
        use std::iter::Iterator;
        self.fields = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [create_time][crate::model::Document::create_time].
    pub fn set_create_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.create_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [create_time][crate::model::Document::create_time].
    pub fn set_or_clear_create_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.create_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [update_time][crate::model::Document::update_time].
    pub fn set_update_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.update_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_time][crate::model::Document::update_time].
    pub fn set_or_clear_update_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.update_time = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for Document {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.Document"
    }
}

/// A message that can hold any of the supported value types.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Value {
    /// Must have a value set.
    pub value_type: std::option::Option<crate::model::value::ValueType>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Value {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [value_type][crate::model::Value::value_type].
    ///
    /// Note that all the setters affecting `value_type` are mutually
    /// exclusive.
    pub fn set_value_type<
        T: std::convert::Into<std::option::Option<crate::model::value::ValueType>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.value_type = v.into();
        self
    }

    /// The value of [value_type][crate::model::Value::value_type]
    /// if it holds a `NullValue`, `None` if the field is not set or
    /// holds a different branch.
    pub fn null_value(&self) -> std::option::Option<&wkt::NullValue> {
        #[allow(unreachable_patterns)]
        self.value_type.as_ref().and_then(|v| match v {
            crate::model::value::ValueType::NullValue(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [value_type][crate::model::Value::value_type]
    /// to hold a `NullValue`.
    ///
    /// Note that all the setters affecting `value_type` are
    /// mutually exclusive.
    pub fn set_null_value<T: std::convert::Into<wkt::NullValue>>(mut self, v: T) -> Self {
        self.value_type =
            std::option::Option::Some(crate::model::value::ValueType::NullValue(v.into()));
        self
    }

    /// The value of [value_type][crate::model::Value::value_type]
    /// if it holds a `BooleanValue`, `None` if the field is not set or
    /// holds a different branch.
    pub fn boolean_value(&self) -> std::option::Option<&bool> {
        #[allow(unreachable_patterns)]
        self.value_type.as_ref().and_then(|v| match v {
            crate::model::value::ValueType::BooleanValue(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [value_type][crate::model::Value::value_type]
    /// to hold a `BooleanValue`.
    ///
    /// Note that all the setters affecting `value_type` are
    /// mutually exclusive.
    pub fn set_boolean_value<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.value_type =
            std::option::Option::Some(crate::model::value::ValueType::BooleanValue(v.into()));
        self
    }

    /// The value of [value_type][crate::model::Value::value_type]
    /// if it holds a `IntegerValue`, `None` if the field is not set or
    /// holds a different branch.
    pub fn integer_value(&self) -> std::option::Option<&i64> {
        #[allow(unreachable_patterns)]
        self.value_type.as_ref().and_then(|v| match v {
            crate::model::value::ValueType::IntegerValue(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [value_type][crate::model::Value::value_type]
    /// to hold a `IntegerValue`.
    ///
    /// Note that all the setters affecting `value_type` are
    /// mutually exclusive.
    pub fn set_integer_value<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
        self.value_type =
            std::option::Option::Some(crate::model::value::ValueType::IntegerValue(v.into()));
        self
    }

    /// The value of [value_type][crate::model::Value::value_type]
    /// if it holds a `DoubleValue`, `None` if the field is not set or
    /// holds a different branch.
    pub fn double_value(&self) -> std::option::Option<&f64> {
        #[allow(unreachable_patterns)]
        self.value_type.as_ref().and_then(|v| match v {
            crate::model::value::ValueType::DoubleValue(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [value_type][crate::model::Value::value_type]
    /// to hold a `DoubleValue`.
    ///
    /// Note that all the setters affecting `value_type` are
    /// mutually exclusive.
    pub fn set_double_value<T: std::convert::Into<f64>>(mut self, v: T) -> Self {
        self.value_type =
            std::option::Option::Some(crate::model::value::ValueType::DoubleValue(v.into()));
        self
    }

    /// The value of [value_type][crate::model::Value::value_type]
    /// if it holds a `TimestampValue`, `None` if the field is not set or
    /// holds a different branch.
    pub fn timestamp_value(&self) -> std::option::Option<&std::boxed::Box<wkt::Timestamp>> {
        #[allow(unreachable_patterns)]
        self.value_type.as_ref().and_then(|v| match v {
            crate::model::value::ValueType::TimestampValue(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [value_type][crate::model::Value::value_type]
    /// to hold a `TimestampValue`.
    ///
    /// Note that all the setters affecting `value_type` are
    /// mutually exclusive.
    pub fn set_timestamp_value<T: std::convert::Into<std::boxed::Box<wkt::Timestamp>>>(
        mut self,
        v: T,
    ) -> Self {
        self.value_type =
            std::option::Option::Some(crate::model::value::ValueType::TimestampValue(v.into()));
        self
    }

    /// The value of [value_type][crate::model::Value::value_type]
    /// if it holds a `StringValue`, `None` if the field is not set or
    /// holds a different branch.
    pub fn string_value(&self) -> std::option::Option<&std::string::String> {
        #[allow(unreachable_patterns)]
        self.value_type.as_ref().and_then(|v| match v {
            crate::model::value::ValueType::StringValue(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [value_type][crate::model::Value::value_type]
    /// to hold a `StringValue`.
    ///
    /// Note that all the setters affecting `value_type` are
    /// mutually exclusive.
    pub fn set_string_value<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.value_type =
            std::option::Option::Some(crate::model::value::ValueType::StringValue(v.into()));
        self
    }

    /// The value of [value_type][crate::model::Value::value_type]
    /// if it holds a `BytesValue`, `None` if the field is not set or
    /// holds a different branch.
    pub fn bytes_value(&self) -> std::option::Option<&::bytes::Bytes> {
        #[allow(unreachable_patterns)]
        self.value_type.as_ref().and_then(|v| match v {
            crate::model::value::ValueType::BytesValue(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [value_type][crate::model::Value::value_type]
    /// to hold a `BytesValue`.
    ///
    /// Note that all the setters affecting `value_type` are
    /// mutually exclusive.
    pub fn set_bytes_value<T: std::convert::Into<::bytes::Bytes>>(mut self, v: T) -> Self {
        self.value_type =
            std::option::Option::Some(crate::model::value::ValueType::BytesValue(v.into()));
        self
    }

    /// The value of [value_type][crate::model::Value::value_type]
    /// if it holds a `ReferenceValue`, `None` if the field is not set or
    /// holds a different branch.
    pub fn reference_value(&self) -> std::option::Option<&std::string::String> {
        #[allow(unreachable_patterns)]
        self.value_type.as_ref().and_then(|v| match v {
            crate::model::value::ValueType::ReferenceValue(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [value_type][crate::model::Value::value_type]
    /// to hold a `ReferenceValue`.
    ///
    /// Note that all the setters affecting `value_type` are
    /// mutually exclusive.
    pub fn set_reference_value<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.value_type =
            std::option::Option::Some(crate::model::value::ValueType::ReferenceValue(v.into()));
        self
    }

    /// The value of [value_type][crate::model::Value::value_type]
    /// if it holds a `GeoPointValue`, `None` if the field is not set or
    /// holds a different branch.
    pub fn geo_point_value(&self) -> std::option::Option<&std::boxed::Box<gtype::model::LatLng>> {
        #[allow(unreachable_patterns)]
        self.value_type.as_ref().and_then(|v| match v {
            crate::model::value::ValueType::GeoPointValue(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [value_type][crate::model::Value::value_type]
    /// to hold a `GeoPointValue`.
    ///
    /// Note that all the setters affecting `value_type` are
    /// mutually exclusive.
    pub fn set_geo_point_value<T: std::convert::Into<std::boxed::Box<gtype::model::LatLng>>>(
        mut self,
        v: T,
    ) -> Self {
        self.value_type =
            std::option::Option::Some(crate::model::value::ValueType::GeoPointValue(v.into()));
        self
    }

    /// The value of [value_type][crate::model::Value::value_type]
    /// if it holds a `ArrayValue`, `None` if the field is not set or
    /// holds a different branch.
    pub fn array_value(&self) -> std::option::Option<&std::boxed::Box<crate::model::ArrayValue>> {
        #[allow(unreachable_patterns)]
        self.value_type.as_ref().and_then(|v| match v {
            crate::model::value::ValueType::ArrayValue(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [value_type][crate::model::Value::value_type]
    /// to hold a `ArrayValue`.
    ///
    /// Note that all the setters affecting `value_type` are
    /// mutually exclusive.
    pub fn set_array_value<T: std::convert::Into<std::boxed::Box<crate::model::ArrayValue>>>(
        mut self,
        v: T,
    ) -> Self {
        self.value_type =
            std::option::Option::Some(crate::model::value::ValueType::ArrayValue(v.into()));
        self
    }

    /// The value of [value_type][crate::model::Value::value_type]
    /// if it holds a `MapValue`, `None` if the field is not set or
    /// holds a different branch.
    pub fn map_value(&self) -> std::option::Option<&std::boxed::Box<crate::model::MapValue>> {
        #[allow(unreachable_patterns)]
        self.value_type.as_ref().and_then(|v| match v {
            crate::model::value::ValueType::MapValue(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [value_type][crate::model::Value::value_type]
    /// to hold a `MapValue`.
    ///
    /// Note that all the setters affecting `value_type` are
    /// mutually exclusive.
    pub fn set_map_value<T: std::convert::Into<std::boxed::Box<crate::model::MapValue>>>(
        mut self,
        v: T,
    ) -> Self {
        self.value_type =
            std::option::Option::Some(crate::model::value::ValueType::MapValue(v.into()));
        self
    }
}

impl wkt::message::Message for Value {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.Value"
    }
}

/// Defines additional types related to [Value].
pub mod value {
    #[allow(unused_imports)]
    use super::*;

    /// Must have a value set.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum ValueType {
        /// A null value.
        NullValue(wkt::NullValue),
        /// A boolean value.
        BooleanValue(bool),
        /// An integer value.
        IntegerValue(i64),
        /// A double value.
        DoubleValue(f64),
        /// A timestamp value.
        ///
        /// Precise only to microseconds. When stored, any additional precision is
        /// rounded down.
        TimestampValue(std::boxed::Box<wkt::Timestamp>),
        /// A string value.
        ///
        /// The string, represented as UTF-8, must not exceed 1 MiB - 89 bytes.
        /// Only the first 1,500 bytes of the UTF-8 representation are considered by
        /// queries.
        StringValue(std::string::String),
        /// A bytes value.
        ///
        /// Must not exceed 1 MiB - 89 bytes.
        /// Only the first 1,500 bytes are considered by queries.
        BytesValue(::bytes::Bytes),
        /// A reference to a document. For example:
        /// `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
        ReferenceValue(std::string::String),
        /// A geo point value representing a point on the surface of Earth.
        GeoPointValue(std::boxed::Box<gtype::model::LatLng>),
        /// An array value.
        ///
        /// Cannot directly contain another array value, though can contain a
        /// map which contains another array.
        ArrayValue(std::boxed::Box<crate::model::ArrayValue>),
        /// A map value.
        MapValue(std::boxed::Box<crate::model::MapValue>),
    }

    impl ValueType {
        /// Initializes the enum to the [NullValue](Self::NullValue) branch.
        pub fn from_null_value(value: impl std::convert::Into<wkt::NullValue>) -> Self {
            Self::NullValue(value.into())
        }
        /// Initializes the enum to the [BooleanValue](Self::BooleanValue) branch.
        pub fn from_boolean_value(value: impl std::convert::Into<bool>) -> Self {
            Self::BooleanValue(value.into())
        }
        /// Initializes the enum to the [IntegerValue](Self::IntegerValue) branch.
        pub fn from_integer_value(value: impl std::convert::Into<i64>) -> Self {
            Self::IntegerValue(value.into())
        }
        /// Initializes the enum to the [DoubleValue](Self::DoubleValue) branch.
        pub fn from_double_value(value: impl std::convert::Into<f64>) -> Self {
            Self::DoubleValue(value.into())
        }
        /// Initializes the enum to the [TimestampValue](Self::TimestampValue) branch.
        pub fn from_timestamp_value(
            value: impl std::convert::Into<std::boxed::Box<wkt::Timestamp>>,
        ) -> Self {
            Self::TimestampValue(value.into())
        }
        /// Initializes the enum to the [StringValue](Self::StringValue) branch.
        pub fn from_string_value(value: impl std::convert::Into<std::string::String>) -> Self {
            Self::StringValue(value.into())
        }
        /// Initializes the enum to the [BytesValue](Self::BytesValue) branch.
        pub fn from_bytes_value(value: impl std::convert::Into<::bytes::Bytes>) -> Self {
            Self::BytesValue(value.into())
        }
        /// Initializes the enum to the [ReferenceValue](Self::ReferenceValue) branch.
        pub fn from_reference_value(value: impl std::convert::Into<std::string::String>) -> Self {
            Self::ReferenceValue(value.into())
        }
        /// Initializes the enum to the [GeoPointValue](Self::GeoPointValue) branch.
        pub fn from_geo_point_value(
            value: impl std::convert::Into<std::boxed::Box<gtype::model::LatLng>>,
        ) -> Self {
            Self::GeoPointValue(value.into())
        }
        /// Initializes the enum to the [ArrayValue](Self::ArrayValue) branch.
        pub fn from_array_value(
            value: impl std::convert::Into<std::boxed::Box<crate::model::ArrayValue>>,
        ) -> Self {
            Self::ArrayValue(value.into())
        }
        /// Initializes the enum to the [MapValue](Self::MapValue) branch.
        pub fn from_map_value(
            value: impl std::convert::Into<std::boxed::Box<crate::model::MapValue>>,
        ) -> Self {
            Self::MapValue(value.into())
        }
    }
}

/// An array value.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ArrayValue {
    /// Values in the array.
    pub values: std::vec::Vec<crate::model::Value>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ArrayValue {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [values][crate::model::ArrayValue::values].
    pub fn set_values<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::Value>,
    {
        use std::iter::Iterator;
        self.values = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for ArrayValue {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.ArrayValue"
    }
}

/// A map value.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct MapValue {
    /// The map's fields.
    ///
    /// The map keys represent field names. Field names matching the regular
    /// expression `__.*__` are reserved. Reserved field names are forbidden except
    /// in certain documented contexts. The map keys, represented as UTF-8, must
    /// not exceed 1,500 bytes and cannot be empty.
    pub fields: std::collections::HashMap<std::string::String, crate::model::Value>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl MapValue {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [fields][crate::model::MapValue::fields].
    pub fn set_fields<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<crate::model::Value>,
    {
        use std::iter::Iterator;
        self.fields = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }
}

impl wkt::message::Message for MapValue {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.MapValue"
    }
}

/// The request for
/// [Firestore.GetDocument][google.firestore.v1.Firestore.GetDocument].
///
/// [google.firestore.v1.Firestore.GetDocument]: crate::client::Firestore::get_document
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct GetDocumentRequest {
    /// Required. The resource name of the Document to get. In the format:
    /// `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
    pub name: std::string::String,

    /// The fields to return. If not set, returns all fields.
    ///
    /// If the document has a field that is not present in this mask, that field
    /// will not be returned in the response.
    pub mask: std::option::Option<crate::model::DocumentMask>,

    /// The consistency mode for this transaction.
    /// If not set, defaults to strong consistency.
    pub consistency_selector:
        std::option::Option<crate::model::get_document_request::ConsistencySelector>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl GetDocumentRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::GetDocumentRequest::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }

    /// Sets the value of [mask][crate::model::GetDocumentRequest::mask].
    pub fn set_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::DocumentMask>,
    {
        self.mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [mask][crate::model::GetDocumentRequest::mask].
    pub fn set_or_clear_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::DocumentMask>,
    {
        self.mask = v.map(|x| x.into());
        self
    }

    /// Sets the value of [consistency_selector][crate::model::GetDocumentRequest::consistency_selector].
    ///
    /// Note that all the setters affecting `consistency_selector` are mutually
    /// exclusive.
    pub fn set_consistency_selector<
        T: std::convert::Into<
                std::option::Option<crate::model::get_document_request::ConsistencySelector>,
            >,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.consistency_selector = v.into();
        self
    }

    /// The value of [consistency_selector][crate::model::GetDocumentRequest::consistency_selector]
    /// if it holds a `Transaction`, `None` if the field is not set or
    /// holds a different branch.
    pub fn transaction(&self) -> std::option::Option<&::bytes::Bytes> {
        #[allow(unreachable_patterns)]
        self.consistency_selector.as_ref().and_then(|v| match v {
            crate::model::get_document_request::ConsistencySelector::Transaction(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [consistency_selector][crate::model::GetDocumentRequest::consistency_selector]
    /// to hold a `Transaction`.
    ///
    /// Note that all the setters affecting `consistency_selector` are
    /// mutually exclusive.
    pub fn set_transaction<T: std::convert::Into<::bytes::Bytes>>(mut self, v: T) -> Self {
        self.consistency_selector = std::option::Option::Some(
            crate::model::get_document_request::ConsistencySelector::Transaction(v.into()),
        );
        self
    }

    /// The value of [consistency_selector][crate::model::GetDocumentRequest::consistency_selector]
    /// if it holds a `ReadTime`, `None` if the field is not set or
    /// holds a different branch.
    pub fn read_time(&self) -> std::option::Option<&std::boxed::Box<wkt::Timestamp>> {
        #[allow(unreachable_patterns)]
        self.consistency_selector.as_ref().and_then(|v| match v {
            crate::model::get_document_request::ConsistencySelector::ReadTime(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [consistency_selector][crate::model::GetDocumentRequest::consistency_selector]
    /// to hold a `ReadTime`.
    ///
    /// Note that all the setters affecting `consistency_selector` are
    /// mutually exclusive.
    pub fn set_read_time<T: std::convert::Into<std::boxed::Box<wkt::Timestamp>>>(
        mut self,
        v: T,
    ) -> Self {
        self.consistency_selector = std::option::Option::Some(
            crate::model::get_document_request::ConsistencySelector::ReadTime(v.into()),
        );
        self
    }
}

impl wkt::message::Message for GetDocumentRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.GetDocumentRequest"
    }
}

/// Defines additional types related to [GetDocumentRequest].
pub mod get_document_request {
    #[allow(unused_imports)]
    use super::*;

    /// The consistency mode for this transaction.
    /// If not set, defaults to strong consistency.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum ConsistencySelector {
        /// Reads the document in a transaction.
        Transaction(::bytes::Bytes),
        /// Reads the version of the document at the given time.
        ///
        /// This must be a microsecond precision timestamp within the past one hour,
        /// or if Point-in-Time Recovery is enabled, can additionally be a whole
        /// minute timestamp within the past 7 days.
        ReadTime(std::boxed::Box<wkt::Timestamp>),
    }

    impl ConsistencySelector {
        /// Initializes the enum to the [Transaction](Self::Transaction) branch.
        pub fn from_transaction(value: impl std::convert::Into<::bytes::Bytes>) -> Self {
            Self::Transaction(value.into())
        }
        /// Initializes the enum to the [ReadTime](Self::ReadTime) branch.
        pub fn from_read_time(
            value: impl std::convert::Into<std::boxed::Box<wkt::Timestamp>>,
        ) -> Self {
            Self::ReadTime(value.into())
        }
    }
}

/// The request for
/// [Firestore.ListDocuments][google.firestore.v1.Firestore.ListDocuments].
///
/// [google.firestore.v1.Firestore.ListDocuments]: crate::client::Firestore::list_documents
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ListDocumentsRequest {
    /// Required. The parent resource name. In the format:
    /// `projects/{project_id}/databases/{database_id}/documents` or
    /// `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
    ///
    /// For example:
    /// `projects/my-project/databases/my-database/documents` or
    /// `projects/my-project/databases/my-database/documents/chatrooms/my-chatroom`
    pub parent: std::string::String,

    /// Optional. The collection ID, relative to `parent`, to list.
    ///
    /// For example: `chatrooms` or `messages`.
    ///
    /// This is optional, and when not provided, Firestore will list documents
    /// from all collections under the provided `parent`.
    pub collection_id: std::string::String,

    /// Optional. The maximum number of documents to return in a single response.
    ///
    /// Firestore may return fewer than this value.
    pub page_size: i32,

    /// Optional. A page token, received from a previous `ListDocuments` response.
    ///
    /// Provide this to retrieve the subsequent page. When paginating, all other
    /// parameters (with the exception of `page_size`) must match the values set
    /// in the request that generated the page token.
    pub page_token: std::string::String,

    /// Optional. The optional ordering of the documents to return.
    ///
    /// For example: `priority desc, __name__ desc`.
    ///
    /// This mirrors the [`ORDER BY`][google.firestore.v1.StructuredQuery.order_by]
    /// used in Firestore queries but in a string representation. When absent,
    /// documents are ordered based on `__name__ ASC`.
    ///
    /// [google.firestore.v1.StructuredQuery.order_by]: crate::model::StructuredQuery::order_by
    pub order_by: std::string::String,

    /// Optional. The fields to return. If not set, returns all fields.
    ///
    /// If a document has a field that is not present in this mask, that field
    /// will not be returned in the response.
    pub mask: std::option::Option<crate::model::DocumentMask>,

    /// If the list should show missing documents.
    ///
    /// A document is missing if it does not exist, but there are sub-documents
    /// nested underneath it. When true, such missing documents will be returned
    /// with a key but will not have fields,
    /// [`create_time`][google.firestore.v1.Document.create_time], or
    /// [`update_time`][google.firestore.v1.Document.update_time] set.
    ///
    /// Requests with `show_missing` may not specify `where` or `order_by`.
    ///
    /// [google.firestore.v1.Document.create_time]: crate::model::Document::create_time
    /// [google.firestore.v1.Document.update_time]: crate::model::Document::update_time
    pub show_missing: bool,

    /// The consistency mode for this transaction.
    /// If not set, defaults to strong consistency.
    pub consistency_selector:
        std::option::Option<crate::model::list_documents_request::ConsistencySelector>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ListDocumentsRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::ListDocumentsRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [collection_id][crate::model::ListDocumentsRequest::collection_id].
    pub fn set_collection_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.collection_id = v.into();
        self
    }

    /// Sets the value of [page_size][crate::model::ListDocumentsRequest::page_size].
    pub fn set_page_size<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.page_size = v.into();
        self
    }

    /// Sets the value of [page_token][crate::model::ListDocumentsRequest::page_token].
    pub fn set_page_token<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.page_token = v.into();
        self
    }

    /// Sets the value of [order_by][crate::model::ListDocumentsRequest::order_by].
    pub fn set_order_by<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.order_by = v.into();
        self
    }

    /// Sets the value of [mask][crate::model::ListDocumentsRequest::mask].
    pub fn set_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::DocumentMask>,
    {
        self.mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [mask][crate::model::ListDocumentsRequest::mask].
    pub fn set_or_clear_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::DocumentMask>,
    {
        self.mask = v.map(|x| x.into());
        self
    }

    /// Sets the value of [show_missing][crate::model::ListDocumentsRequest::show_missing].
    pub fn set_show_missing<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.show_missing = v.into();
        self
    }

    /// Sets the value of [consistency_selector][crate::model::ListDocumentsRequest::consistency_selector].
    ///
    /// Note that all the setters affecting `consistency_selector` are mutually
    /// exclusive.
    pub fn set_consistency_selector<
        T: std::convert::Into<
                std::option::Option<crate::model::list_documents_request::ConsistencySelector>,
            >,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.consistency_selector = v.into();
        self
    }

    /// The value of [consistency_selector][crate::model::ListDocumentsRequest::consistency_selector]
    /// if it holds a `Transaction`, `None` if the field is not set or
    /// holds a different branch.
    pub fn transaction(&self) -> std::option::Option<&::bytes::Bytes> {
        #[allow(unreachable_patterns)]
        self.consistency_selector.as_ref().and_then(|v| match v {
            crate::model::list_documents_request::ConsistencySelector::Transaction(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [consistency_selector][crate::model::ListDocumentsRequest::consistency_selector]
    /// to hold a `Transaction`.
    ///
    /// Note that all the setters affecting `consistency_selector` are
    /// mutually exclusive.
    pub fn set_transaction<T: std::convert::Into<::bytes::Bytes>>(mut self, v: T) -> Self {
        self.consistency_selector = std::option::Option::Some(
            crate::model::list_documents_request::ConsistencySelector::Transaction(v.into()),
        );
        self
    }

    /// The value of [consistency_selector][crate::model::ListDocumentsRequest::consistency_selector]
    /// if it holds a `ReadTime`, `None` if the field is not set or
    /// holds a different branch.
    pub fn read_time(&self) -> std::option::Option<&std::boxed::Box<wkt::Timestamp>> {
        #[allow(unreachable_patterns)]
        self.consistency_selector.as_ref().and_then(|v| match v {
            crate::model::list_documents_request::ConsistencySelector::ReadTime(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [consistency_selector][crate::model::ListDocumentsRequest::consistency_selector]
    /// to hold a `ReadTime`.
    ///
    /// Note that all the setters affecting `consistency_selector` are
    /// mutually exclusive.
    pub fn set_read_time<T: std::convert::Into<std::boxed::Box<wkt::Timestamp>>>(
        mut self,
        v: T,
    ) -> Self {
        self.consistency_selector = std::option::Option::Some(
            crate::model::list_documents_request::ConsistencySelector::ReadTime(v.into()),
        );
        self
    }
}

impl wkt::message::Message for ListDocumentsRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.ListDocumentsRequest"
    }
}

/// Defines additional types related to [ListDocumentsRequest].
pub mod list_documents_request {
    #[allow(unused_imports)]
    use super::*;

    /// The consistency mode for this transaction.
    /// If not set, defaults to strong consistency.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum ConsistencySelector {
        /// Perform the read as part of an already active transaction.
        Transaction(::bytes::Bytes),
        /// Perform the read at the provided time.
        ///
        /// This must be a microsecond precision timestamp within the past one hour,
        /// or if Point-in-Time Recovery is enabled, can additionally be a whole
        /// minute timestamp within the past 7 days.
        ReadTime(std::boxed::Box<wkt::Timestamp>),
    }

    impl ConsistencySelector {
        /// Initializes the enum to the [Transaction](Self::Transaction) branch.
        pub fn from_transaction(value: impl std::convert::Into<::bytes::Bytes>) -> Self {
            Self::Transaction(value.into())
        }
        /// Initializes the enum to the [ReadTime](Self::ReadTime) branch.
        pub fn from_read_time(
            value: impl std::convert::Into<std::boxed::Box<wkt::Timestamp>>,
        ) -> Self {
            Self::ReadTime(value.into())
        }
    }
}

/// The response for
/// [Firestore.ListDocuments][google.firestore.v1.Firestore.ListDocuments].
///
/// [google.firestore.v1.Firestore.ListDocuments]: crate::client::Firestore::list_documents
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ListDocumentsResponse {
    /// The Documents found.
    pub documents: std::vec::Vec<crate::model::Document>,

    /// A token to retrieve the next page of documents.
    ///
    /// If this field is omitted, there are no subsequent pages.
    pub next_page_token: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ListDocumentsResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [documents][crate::model::ListDocumentsResponse::documents].
    pub fn set_documents<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::Document>,
    {
        use std::iter::Iterator;
        self.documents = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [next_page_token][crate::model::ListDocumentsResponse::next_page_token].
    pub fn set_next_page_token<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.next_page_token = v.into();
        self
    }
}

impl wkt::message::Message for ListDocumentsResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.ListDocumentsResponse"
    }
}

#[doc(hidden)]
impl gax::paginator::internal::PageableResponse for ListDocumentsResponse {
    type PageItem = crate::model::Document;

    fn items(self) -> std::vec::Vec<Self::PageItem> {
        self.documents
    }

    fn next_page_token(&self) -> std::string::String {
        use std::clone::Clone;
        self.next_page_token.clone()
    }
}

/// The request for
/// [Firestore.CreateDocument][google.firestore.v1.Firestore.CreateDocument].
///
/// [google.firestore.v1.Firestore.CreateDocument]: crate::client::Firestore::create_document
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct CreateDocumentRequest {
    /// Required. The parent resource. For example:
    /// `projects/{project_id}/databases/{database_id}/documents` or
    /// `projects/{project_id}/databases/{database_id}/documents/chatrooms/{chatroom_id}`
    pub parent: std::string::String,

    /// Required. The collection ID, relative to `parent`, to list. For example:
    /// `chatrooms`.
    pub collection_id: std::string::String,

    /// The client-assigned document ID to use for this document.
    ///
    /// Optional. If not specified, an ID will be assigned by the service.
    pub document_id: std::string::String,

    /// Required. The document to create. `name` must not be set.
    pub document: std::option::Option<crate::model::Document>,

    /// The fields to return. If not set, returns all fields.
    ///
    /// If the document has a field that is not present in this mask, that field
    /// will not be returned in the response.
    pub mask: std::option::Option<crate::model::DocumentMask>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl CreateDocumentRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::CreateDocumentRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [collection_id][crate::model::CreateDocumentRequest::collection_id].
    pub fn set_collection_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.collection_id = v.into();
        self
    }

    /// Sets the value of [document_id][crate::model::CreateDocumentRequest::document_id].
    pub fn set_document_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.document_id = v.into();
        self
    }

    /// Sets the value of [document][crate::model::CreateDocumentRequest::document].
    pub fn set_document<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Document>,
    {
        self.document = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [document][crate::model::CreateDocumentRequest::document].
    pub fn set_or_clear_document<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Document>,
    {
        self.document = v.map(|x| x.into());
        self
    }

    /// Sets the value of [mask][crate::model::CreateDocumentRequest::mask].
    pub fn set_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::DocumentMask>,
    {
        self.mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [mask][crate::model::CreateDocumentRequest::mask].
    pub fn set_or_clear_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::DocumentMask>,
    {
        self.mask = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for CreateDocumentRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.CreateDocumentRequest"
    }
}

/// The request for
/// [Firestore.UpdateDocument][google.firestore.v1.Firestore.UpdateDocument].
///
/// [google.firestore.v1.Firestore.UpdateDocument]: crate::client::Firestore::update_document
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct UpdateDocumentRequest {
    /// Required. The updated document.
    /// Creates the document if it does not already exist.
    pub document: std::option::Option<crate::model::Document>,

    /// The fields to update.
    /// None of the field paths in the mask may contain a reserved name.
    ///
    /// If the document exists on the server and has fields not referenced in the
    /// mask, they are left unchanged.
    /// Fields referenced in the mask, but not present in the input document, are
    /// deleted from the document on the server.
    pub update_mask: std::option::Option<crate::model::DocumentMask>,

    /// The fields to return. If not set, returns all fields.
    ///
    /// If the document has a field that is not present in this mask, that field
    /// will not be returned in the response.
    pub mask: std::option::Option<crate::model::DocumentMask>,

    /// An optional precondition on the document.
    /// The request will fail if this is set and not met by the target document.
    pub current_document: std::option::Option<crate::model::Precondition>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl UpdateDocumentRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [document][crate::model::UpdateDocumentRequest::document].
    pub fn set_document<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Document>,
    {
        self.document = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [document][crate::model::UpdateDocumentRequest::document].
    pub fn set_or_clear_document<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Document>,
    {
        self.document = v.map(|x| x.into());
        self
    }

    /// Sets the value of [update_mask][crate::model::UpdateDocumentRequest::update_mask].
    pub fn set_update_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::DocumentMask>,
    {
        self.update_mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_mask][crate::model::UpdateDocumentRequest::update_mask].
    pub fn set_or_clear_update_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::DocumentMask>,
    {
        self.update_mask = v.map(|x| x.into());
        self
    }

    /// Sets the value of [mask][crate::model::UpdateDocumentRequest::mask].
    pub fn set_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::DocumentMask>,
    {
        self.mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [mask][crate::model::UpdateDocumentRequest::mask].
    pub fn set_or_clear_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::DocumentMask>,
    {
        self.mask = v.map(|x| x.into());
        self
    }

    /// Sets the value of [current_document][crate::model::UpdateDocumentRequest::current_document].
    pub fn set_current_document<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Precondition>,
    {
        self.current_document = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [current_document][crate::model::UpdateDocumentRequest::current_document].
    pub fn set_or_clear_current_document<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Precondition>,
    {
        self.current_document = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for UpdateDocumentRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.UpdateDocumentRequest"
    }
}

/// The request for
/// [Firestore.DeleteDocument][google.firestore.v1.Firestore.DeleteDocument].
///
/// [google.firestore.v1.Firestore.DeleteDocument]: crate::client::Firestore::delete_document
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct DeleteDocumentRequest {
    /// Required. The resource name of the Document to delete. In the format:
    /// `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
    pub name: std::string::String,

    /// An optional precondition on the document.
    /// The request will fail if this is set and not met by the target document.
    pub current_document: std::option::Option<crate::model::Precondition>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl DeleteDocumentRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [name][crate::model::DeleteDocumentRequest::name].
    pub fn set_name<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.name = v.into();
        self
    }

    /// Sets the value of [current_document][crate::model::DeleteDocumentRequest::current_document].
    pub fn set_current_document<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Precondition>,
    {
        self.current_document = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [current_document][crate::model::DeleteDocumentRequest::current_document].
    pub fn set_or_clear_current_document<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Precondition>,
    {
        self.current_document = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for DeleteDocumentRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.DeleteDocumentRequest"
    }
}

/// The request for
/// [Firestore.BatchGetDocuments][google.firestore.v1.Firestore.BatchGetDocuments].
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct BatchGetDocumentsRequest {
    /// Required. The database name. In the format:
    /// `projects/{project_id}/databases/{database_id}`.
    pub database: std::string::String,

    /// The names of the documents to retrieve. In the format:
    /// `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
    /// The request will fail if any of the document is not a child resource of the
    /// given `database`. Duplicate names will be elided.
    pub documents: std::vec::Vec<std::string::String>,

    /// The fields to return. If not set, returns all fields.
    ///
    /// If a document has a field that is not present in this mask, that field will
    /// not be returned in the response.
    pub mask: std::option::Option<crate::model::DocumentMask>,

    /// The consistency mode for this transaction.
    /// If not set, defaults to strong consistency.
    pub consistency_selector:
        std::option::Option<crate::model::batch_get_documents_request::ConsistencySelector>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl BatchGetDocumentsRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [database][crate::model::BatchGetDocumentsRequest::database].
    pub fn set_database<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.database = v.into();
        self
    }

    /// Sets the value of [documents][crate::model::BatchGetDocumentsRequest::documents].
    pub fn set_documents<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.documents = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [mask][crate::model::BatchGetDocumentsRequest::mask].
    pub fn set_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::DocumentMask>,
    {
        self.mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [mask][crate::model::BatchGetDocumentsRequest::mask].
    pub fn set_or_clear_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::DocumentMask>,
    {
        self.mask = v.map(|x| x.into());
        self
    }

    /// Sets the value of [consistency_selector][crate::model::BatchGetDocumentsRequest::consistency_selector].
    ///
    /// Note that all the setters affecting `consistency_selector` are mutually
    /// exclusive.
    pub fn set_consistency_selector<
        T: std::convert::Into<
                std::option::Option<crate::model::batch_get_documents_request::ConsistencySelector>,
            >,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.consistency_selector = v.into();
        self
    }

    /// The value of [consistency_selector][crate::model::BatchGetDocumentsRequest::consistency_selector]
    /// if it holds a `Transaction`, `None` if the field is not set or
    /// holds a different branch.
    pub fn transaction(&self) -> std::option::Option<&::bytes::Bytes> {
        #[allow(unreachable_patterns)]
        self.consistency_selector.as_ref().and_then(|v| match v {
            crate::model::batch_get_documents_request::ConsistencySelector::Transaction(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [consistency_selector][crate::model::BatchGetDocumentsRequest::consistency_selector]
    /// to hold a `Transaction`.
    ///
    /// Note that all the setters affecting `consistency_selector` are
    /// mutually exclusive.
    pub fn set_transaction<T: std::convert::Into<::bytes::Bytes>>(mut self, v: T) -> Self {
        self.consistency_selector = std::option::Option::Some(
            crate::model::batch_get_documents_request::ConsistencySelector::Transaction(v.into()),
        );
        self
    }

    /// The value of [consistency_selector][crate::model::BatchGetDocumentsRequest::consistency_selector]
    /// if it holds a `NewTransaction`, `None` if the field is not set or
    /// holds a different branch.
    pub fn new_transaction(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::TransactionOptions>> {
        #[allow(unreachable_patterns)]
        self.consistency_selector.as_ref().and_then(|v| match v {
            crate::model::batch_get_documents_request::ConsistencySelector::NewTransaction(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [consistency_selector][crate::model::BatchGetDocumentsRequest::consistency_selector]
    /// to hold a `NewTransaction`.
    ///
    /// Note that all the setters affecting `consistency_selector` are
    /// mutually exclusive.
    pub fn set_new_transaction<
        T: std::convert::Into<std::boxed::Box<crate::model::TransactionOptions>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.consistency_selector = std::option::Option::Some(
            crate::model::batch_get_documents_request::ConsistencySelector::NewTransaction(
                v.into(),
            ),
        );
        self
    }

    /// The value of [consistency_selector][crate::model::BatchGetDocumentsRequest::consistency_selector]
    /// if it holds a `ReadTime`, `None` if the field is not set or
    /// holds a different branch.
    pub fn read_time(&self) -> std::option::Option<&std::boxed::Box<wkt::Timestamp>> {
        #[allow(unreachable_patterns)]
        self.consistency_selector.as_ref().and_then(|v| match v {
            crate::model::batch_get_documents_request::ConsistencySelector::ReadTime(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [consistency_selector][crate::model::BatchGetDocumentsRequest::consistency_selector]
    /// to hold a `ReadTime`.
    ///
    /// Note that all the setters affecting `consistency_selector` are
    /// mutually exclusive.
    pub fn set_read_time<T: std::convert::Into<std::boxed::Box<wkt::Timestamp>>>(
        mut self,
        v: T,
    ) -> Self {
        self.consistency_selector = std::option::Option::Some(
            crate::model::batch_get_documents_request::ConsistencySelector::ReadTime(v.into()),
        );
        self
    }
}

impl wkt::message::Message for BatchGetDocumentsRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.BatchGetDocumentsRequest"
    }
}

/// Defines additional types related to [BatchGetDocumentsRequest].
pub mod batch_get_documents_request {
    #[allow(unused_imports)]
    use super::*;

    /// The consistency mode for this transaction.
    /// If not set, defaults to strong consistency.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum ConsistencySelector {
        /// Reads documents in a transaction.
        Transaction(::bytes::Bytes),
        /// Starts a new transaction and reads the documents.
        /// Defaults to a read-only transaction.
        /// The new transaction ID will be returned as the first response in the
        /// stream.
        NewTransaction(std::boxed::Box<crate::model::TransactionOptions>),
        /// Reads documents as they were at the given time.
        ///
        /// This must be a microsecond precision timestamp within the past one hour,
        /// or if Point-in-Time Recovery is enabled, can additionally be a whole
        /// minute timestamp within the past 7 days.
        ReadTime(std::boxed::Box<wkt::Timestamp>),
    }

    impl ConsistencySelector {
        /// Initializes the enum to the [Transaction](Self::Transaction) branch.
        pub fn from_transaction(value: impl std::convert::Into<::bytes::Bytes>) -> Self {
            Self::Transaction(value.into())
        }
        /// Initializes the enum to the [NewTransaction](Self::NewTransaction) branch.
        pub fn from_new_transaction(
            value: impl std::convert::Into<std::boxed::Box<crate::model::TransactionOptions>>,
        ) -> Self {
            Self::NewTransaction(value.into())
        }
        /// Initializes the enum to the [ReadTime](Self::ReadTime) branch.
        pub fn from_read_time(
            value: impl std::convert::Into<std::boxed::Box<wkt::Timestamp>>,
        ) -> Self {
            Self::ReadTime(value.into())
        }
    }
}

/// The streamed response for
/// [Firestore.BatchGetDocuments][google.firestore.v1.Firestore.BatchGetDocuments].
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct BatchGetDocumentsResponse {
    /// The transaction that was started as part of this request.
    /// Will only be set in the first response, and only if
    /// [BatchGetDocumentsRequest.new_transaction][google.firestore.v1.BatchGetDocumentsRequest.new_transaction]
    /// was set in the request.
    ///
    /// [google.firestore.v1.BatchGetDocumentsRequest.new_transaction]: crate::model::BatchGetDocumentsRequest::consistency_selector
    pub transaction: ::bytes::Bytes,

    /// The time at which the document was read.
    /// This may be monotically increasing, in this case the previous documents in
    /// the result stream are guaranteed not to have changed between their
    /// read_time and this one.
    pub read_time: std::option::Option<wkt::Timestamp>,

    /// A single result.
    /// This can be empty if the server is just returning a transaction.
    pub result: std::option::Option<crate::model::batch_get_documents_response::Result>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl BatchGetDocumentsResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [transaction][crate::model::BatchGetDocumentsResponse::transaction].
    pub fn set_transaction<T: std::convert::Into<::bytes::Bytes>>(mut self, v: T) -> Self {
        self.transaction = v.into();
        self
    }

    /// Sets the value of [read_time][crate::model::BatchGetDocumentsResponse::read_time].
    pub fn set_read_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.read_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [read_time][crate::model::BatchGetDocumentsResponse::read_time].
    pub fn set_or_clear_read_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.read_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [result][crate::model::BatchGetDocumentsResponse::result].
    ///
    /// Note that all the setters affecting `result` are mutually
    /// exclusive.
    pub fn set_result<
        T: std::convert::Into<std::option::Option<crate::model::batch_get_documents_response::Result>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.result = v.into();
        self
    }

    /// The value of [result][crate::model::BatchGetDocumentsResponse::result]
    /// if it holds a `Found`, `None` if the field is not set or
    /// holds a different branch.
    pub fn found(&self) -> std::option::Option<&std::boxed::Box<crate::model::Document>> {
        #[allow(unreachable_patterns)]
        self.result.as_ref().and_then(|v| match v {
            crate::model::batch_get_documents_response::Result::Found(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [result][crate::model::BatchGetDocumentsResponse::result]
    /// to hold a `Found`.
    ///
    /// Note that all the setters affecting `result` are
    /// mutually exclusive.
    pub fn set_found<T: std::convert::Into<std::boxed::Box<crate::model::Document>>>(
        mut self,
        v: T,
    ) -> Self {
        self.result = std::option::Option::Some(
            crate::model::batch_get_documents_response::Result::Found(v.into()),
        );
        self
    }

    /// The value of [result][crate::model::BatchGetDocumentsResponse::result]
    /// if it holds a `Missing`, `None` if the field is not set or
    /// holds a different branch.
    pub fn missing(&self) -> std::option::Option<&std::string::String> {
        #[allow(unreachable_patterns)]
        self.result.as_ref().and_then(|v| match v {
            crate::model::batch_get_documents_response::Result::Missing(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [result][crate::model::BatchGetDocumentsResponse::result]
    /// to hold a `Missing`.
    ///
    /// Note that all the setters affecting `result` are
    /// mutually exclusive.
    pub fn set_missing<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.result = std::option::Option::Some(
            crate::model::batch_get_documents_response::Result::Missing(v.into()),
        );
        self
    }
}

impl wkt::message::Message for BatchGetDocumentsResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.BatchGetDocumentsResponse"
    }
}

/// Defines additional types related to [BatchGetDocumentsResponse].
pub mod batch_get_documents_response {
    #[allow(unused_imports)]
    use super::*;

    /// A single result.
    /// This can be empty if the server is just returning a transaction.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Result {
        /// A document that was requested.
        Found(std::boxed::Box<crate::model::Document>),
        /// A document name that was requested but does not exist. In the format:
        /// `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
        Missing(std::string::String),
    }

    impl Result {
        /// Initializes the enum to the [Found](Self::Found) branch.
        pub fn from_found(
            value: impl std::convert::Into<std::boxed::Box<crate::model::Document>>,
        ) -> Self {
            Self::Found(value.into())
        }
        /// Initializes the enum to the [Missing](Self::Missing) branch.
        pub fn from_missing(value: impl std::convert::Into<std::string::String>) -> Self {
            Self::Missing(value.into())
        }
    }
}

/// The request for
/// [Firestore.BeginTransaction][google.firestore.v1.Firestore.BeginTransaction].
///
/// [google.firestore.v1.Firestore.BeginTransaction]: crate::client::Firestore::begin_transaction
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct BeginTransactionRequest {
    /// Required. The database name. In the format:
    /// `projects/{project_id}/databases/{database_id}`.
    pub database: std::string::String,

    /// The options for the transaction.
    /// Defaults to a read-write transaction.
    pub options: std::option::Option<crate::model::TransactionOptions>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl BeginTransactionRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [database][crate::model::BeginTransactionRequest::database].
    pub fn set_database<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.database = v.into();
        self
    }

    /// Sets the value of [options][crate::model::BeginTransactionRequest::options].
    pub fn set_options<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::TransactionOptions>,
    {
        self.options = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [options][crate::model::BeginTransactionRequest::options].
    pub fn set_or_clear_options<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::TransactionOptions>,
    {
        self.options = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for BeginTransactionRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.BeginTransactionRequest"
    }
}

/// The response for
/// [Firestore.BeginTransaction][google.firestore.v1.Firestore.BeginTransaction].
///
/// [google.firestore.v1.Firestore.BeginTransaction]: crate::client::Firestore::begin_transaction
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct BeginTransactionResponse {
    /// The transaction that was started.
    pub transaction: ::bytes::Bytes,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl BeginTransactionResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [transaction][crate::model::BeginTransactionResponse::transaction].
    pub fn set_transaction<T: std::convert::Into<::bytes::Bytes>>(mut self, v: T) -> Self {
        self.transaction = v.into();
        self
    }
}

impl wkt::message::Message for BeginTransactionResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.BeginTransactionResponse"
    }
}

/// The request for [Firestore.Commit][google.firestore.v1.Firestore.Commit].
///
/// [google.firestore.v1.Firestore.Commit]: crate::client::Firestore::commit
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct CommitRequest {
    /// Required. The database name. In the format:
    /// `projects/{project_id}/databases/{database_id}`.
    pub database: std::string::String,

    /// The writes to apply.
    ///
    /// Always executed atomically and in order.
    pub writes: std::vec::Vec<crate::model::Write>,

    /// If set, applies all writes in this transaction, and commits it.
    pub transaction: ::bytes::Bytes,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl CommitRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [database][crate::model::CommitRequest::database].
    pub fn set_database<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.database = v.into();
        self
    }

    /// Sets the value of [writes][crate::model::CommitRequest::writes].
    pub fn set_writes<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::Write>,
    {
        use std::iter::Iterator;
        self.writes = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [transaction][crate::model::CommitRequest::transaction].
    pub fn set_transaction<T: std::convert::Into<::bytes::Bytes>>(mut self, v: T) -> Self {
        self.transaction = v.into();
        self
    }
}

impl wkt::message::Message for CommitRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.CommitRequest"
    }
}

/// The response for [Firestore.Commit][google.firestore.v1.Firestore.Commit].
///
/// [google.firestore.v1.Firestore.Commit]: crate::client::Firestore::commit
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct CommitResponse {
    /// The result of applying the writes.
    ///
    /// This i-th write result corresponds to the i-th write in the
    /// request.
    pub write_results: std::vec::Vec<crate::model::WriteResult>,

    /// The time at which the commit occurred. Any read with an equal or greater
    /// `read_time` is guaranteed to see the effects of the commit.
    pub commit_time: std::option::Option<wkt::Timestamp>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl CommitResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [write_results][crate::model::CommitResponse::write_results].
    pub fn set_write_results<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::WriteResult>,
    {
        use std::iter::Iterator;
        self.write_results = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [commit_time][crate::model::CommitResponse::commit_time].
    pub fn set_commit_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.commit_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [commit_time][crate::model::CommitResponse::commit_time].
    pub fn set_or_clear_commit_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.commit_time = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for CommitResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.CommitResponse"
    }
}

/// The request for [Firestore.Rollback][google.firestore.v1.Firestore.Rollback].
///
/// [google.firestore.v1.Firestore.Rollback]: crate::client::Firestore::rollback
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct RollbackRequest {
    /// Required. The database name. In the format:
    /// `projects/{project_id}/databases/{database_id}`.
    pub database: std::string::String,

    /// Required. The transaction to roll back.
    pub transaction: ::bytes::Bytes,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl RollbackRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [database][crate::model::RollbackRequest::database].
    pub fn set_database<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.database = v.into();
        self
    }

    /// Sets the value of [transaction][crate::model::RollbackRequest::transaction].
    pub fn set_transaction<T: std::convert::Into<::bytes::Bytes>>(mut self, v: T) -> Self {
        self.transaction = v.into();
        self
    }
}

impl wkt::message::Message for RollbackRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.RollbackRequest"
    }
}

/// The request for [Firestore.RunQuery][google.firestore.v1.Firestore.RunQuery].
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct RunQueryRequest {
    /// Required. The parent resource name. In the format:
    /// `projects/{project_id}/databases/{database_id}/documents` or
    /// `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
    /// For example:
    /// `projects/my-project/databases/my-database/documents` or
    /// `projects/my-project/databases/my-database/documents/chatrooms/my-chatroom`
    pub parent: std::string::String,

    /// Optional. Explain options for the query. If set, additional query
    /// statistics will be returned. If not, only query results will be returned.
    pub explain_options: std::option::Option<crate::model::ExplainOptions>,

    /// The query to run.
    pub query_type: std::option::Option<crate::model::run_query_request::QueryType>,

    /// The consistency mode for this transaction.
    /// If not set, defaults to strong consistency.
    pub consistency_selector:
        std::option::Option<crate::model::run_query_request::ConsistencySelector>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl RunQueryRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::RunQueryRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [explain_options][crate::model::RunQueryRequest::explain_options].
    pub fn set_explain_options<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::ExplainOptions>,
    {
        self.explain_options = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [explain_options][crate::model::RunQueryRequest::explain_options].
    pub fn set_or_clear_explain_options<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::ExplainOptions>,
    {
        self.explain_options = v.map(|x| x.into());
        self
    }

    /// Sets the value of [query_type][crate::model::RunQueryRequest::query_type].
    ///
    /// Note that all the setters affecting `query_type` are mutually
    /// exclusive.
    pub fn set_query_type<
        T: std::convert::Into<std::option::Option<crate::model::run_query_request::QueryType>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.query_type = v.into();
        self
    }

    /// The value of [query_type][crate::model::RunQueryRequest::query_type]
    /// if it holds a `StructuredQuery`, `None` if the field is not set or
    /// holds a different branch.
    pub fn structured_query(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::StructuredQuery>> {
        #[allow(unreachable_patterns)]
        self.query_type.as_ref().and_then(|v| match v {
            crate::model::run_query_request::QueryType::StructuredQuery(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [query_type][crate::model::RunQueryRequest::query_type]
    /// to hold a `StructuredQuery`.
    ///
    /// Note that all the setters affecting `query_type` are
    /// mutually exclusive.
    pub fn set_structured_query<
        T: std::convert::Into<std::boxed::Box<crate::model::StructuredQuery>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.query_type = std::option::Option::Some(
            crate::model::run_query_request::QueryType::StructuredQuery(v.into()),
        );
        self
    }

    /// Sets the value of [consistency_selector][crate::model::RunQueryRequest::consistency_selector].
    ///
    /// Note that all the setters affecting `consistency_selector` are mutually
    /// exclusive.
    pub fn set_consistency_selector<
        T: std::convert::Into<
                std::option::Option<crate::model::run_query_request::ConsistencySelector>,
            >,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.consistency_selector = v.into();
        self
    }

    /// The value of [consistency_selector][crate::model::RunQueryRequest::consistency_selector]
    /// if it holds a `Transaction`, `None` if the field is not set or
    /// holds a different branch.
    pub fn transaction(&self) -> std::option::Option<&::bytes::Bytes> {
        #[allow(unreachable_patterns)]
        self.consistency_selector.as_ref().and_then(|v| match v {
            crate::model::run_query_request::ConsistencySelector::Transaction(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [consistency_selector][crate::model::RunQueryRequest::consistency_selector]
    /// to hold a `Transaction`.
    ///
    /// Note that all the setters affecting `consistency_selector` are
    /// mutually exclusive.
    pub fn set_transaction<T: std::convert::Into<::bytes::Bytes>>(mut self, v: T) -> Self {
        self.consistency_selector = std::option::Option::Some(
            crate::model::run_query_request::ConsistencySelector::Transaction(v.into()),
        );
        self
    }

    /// The value of [consistency_selector][crate::model::RunQueryRequest::consistency_selector]
    /// if it holds a `NewTransaction`, `None` if the field is not set or
    /// holds a different branch.
    pub fn new_transaction(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::TransactionOptions>> {
        #[allow(unreachable_patterns)]
        self.consistency_selector.as_ref().and_then(|v| match v {
            crate::model::run_query_request::ConsistencySelector::NewTransaction(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [consistency_selector][crate::model::RunQueryRequest::consistency_selector]
    /// to hold a `NewTransaction`.
    ///
    /// Note that all the setters affecting `consistency_selector` are
    /// mutually exclusive.
    pub fn set_new_transaction<
        T: std::convert::Into<std::boxed::Box<crate::model::TransactionOptions>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.consistency_selector = std::option::Option::Some(
            crate::model::run_query_request::ConsistencySelector::NewTransaction(v.into()),
        );
        self
    }

    /// The value of [consistency_selector][crate::model::RunQueryRequest::consistency_selector]
    /// if it holds a `ReadTime`, `None` if the field is not set or
    /// holds a different branch.
    pub fn read_time(&self) -> std::option::Option<&std::boxed::Box<wkt::Timestamp>> {
        #[allow(unreachable_patterns)]
        self.consistency_selector.as_ref().and_then(|v| match v {
            crate::model::run_query_request::ConsistencySelector::ReadTime(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [consistency_selector][crate::model::RunQueryRequest::consistency_selector]
    /// to hold a `ReadTime`.
    ///
    /// Note that all the setters affecting `consistency_selector` are
    /// mutually exclusive.
    pub fn set_read_time<T: std::convert::Into<std::boxed::Box<wkt::Timestamp>>>(
        mut self,
        v: T,
    ) -> Self {
        self.consistency_selector = std::option::Option::Some(
            crate::model::run_query_request::ConsistencySelector::ReadTime(v.into()),
        );
        self
    }
}

impl wkt::message::Message for RunQueryRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.RunQueryRequest"
    }
}

/// Defines additional types related to [RunQueryRequest].
pub mod run_query_request {
    #[allow(unused_imports)]
    use super::*;

    /// The query to run.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum QueryType {
        /// A structured query.
        StructuredQuery(std::boxed::Box<crate::model::StructuredQuery>),
    }

    impl QueryType {
        /// Initializes the enum to the [StructuredQuery](Self::StructuredQuery) branch.
        pub fn from_structured_query(
            value: impl std::convert::Into<std::boxed::Box<crate::model::StructuredQuery>>,
        ) -> Self {
            Self::StructuredQuery(value.into())
        }
    }

    /// The consistency mode for this transaction.
    /// If not set, defaults to strong consistency.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum ConsistencySelector {
        /// Run the query within an already active transaction.
        ///
        /// The value here is the opaque transaction ID to execute the query in.
        Transaction(::bytes::Bytes),
        /// Starts a new transaction and reads the documents.
        /// Defaults to a read-only transaction.
        /// The new transaction ID will be returned as the first response in the
        /// stream.
        NewTransaction(std::boxed::Box<crate::model::TransactionOptions>),
        /// Reads documents as they were at the given time.
        ///
        /// This must be a microsecond precision timestamp within the past one hour,
        /// or if Point-in-Time Recovery is enabled, can additionally be a whole
        /// minute timestamp within the past 7 days.
        ReadTime(std::boxed::Box<wkt::Timestamp>),
    }

    impl ConsistencySelector {
        /// Initializes the enum to the [Transaction](Self::Transaction) branch.
        pub fn from_transaction(value: impl std::convert::Into<::bytes::Bytes>) -> Self {
            Self::Transaction(value.into())
        }
        /// Initializes the enum to the [NewTransaction](Self::NewTransaction) branch.
        pub fn from_new_transaction(
            value: impl std::convert::Into<std::boxed::Box<crate::model::TransactionOptions>>,
        ) -> Self {
            Self::NewTransaction(value.into())
        }
        /// Initializes the enum to the [ReadTime](Self::ReadTime) branch.
        pub fn from_read_time(
            value: impl std::convert::Into<std::boxed::Box<wkt::Timestamp>>,
        ) -> Self {
            Self::ReadTime(value.into())
        }
    }
}

/// The response for
/// [Firestore.RunQuery][google.firestore.v1.Firestore.RunQuery].
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct RunQueryResponse {
    /// The transaction that was started as part of this request.
    /// Can only be set in the first response, and only if
    /// [RunQueryRequest.new_transaction][google.firestore.v1.RunQueryRequest.new_transaction]
    /// was set in the request. If set, no other fields will be set in this
    /// response.
    ///
    /// [google.firestore.v1.RunQueryRequest.new_transaction]: crate::model::RunQueryRequest::consistency_selector
    pub transaction: ::bytes::Bytes,

    /// A query result, not set when reporting partial progress.
    pub document: std::option::Option<crate::model::Document>,

    /// The time at which the document was read. This may be monotonically
    /// increasing; in this case, the previous documents in the result stream are
    /// guaranteed not to have changed between their `read_time` and this one.
    ///
    /// If the query returns no results, a response with `read_time` and no
    /// `document` will be sent, and this represents the time at which the query
    /// was run.
    pub read_time: std::option::Option<wkt::Timestamp>,

    /// The number of results that have been skipped due to an offset between
    /// the last response and the current response.
    pub skipped_results: i32,

    /// Query explain metrics. This is only present when the
    /// [RunQueryRequest.explain_options][google.firestore.v1.RunQueryRequest.explain_options]
    /// is provided, and it is sent only once with the last response in the stream.
    ///
    /// [google.firestore.v1.RunQueryRequest.explain_options]: crate::model::RunQueryRequest::explain_options
    pub explain_metrics: std::option::Option<crate::model::ExplainMetrics>,

    /// The continuation mode for the query. If present, it indicates the current
    /// query response stream has finished. This can be set with or without a
    /// `document` present, but when set, no more results are returned.
    pub continuation_selector:
        std::option::Option<crate::model::run_query_response::ContinuationSelector>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl RunQueryResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [transaction][crate::model::RunQueryResponse::transaction].
    pub fn set_transaction<T: std::convert::Into<::bytes::Bytes>>(mut self, v: T) -> Self {
        self.transaction = v.into();
        self
    }

    /// Sets the value of [document][crate::model::RunQueryResponse::document].
    pub fn set_document<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Document>,
    {
        self.document = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [document][crate::model::RunQueryResponse::document].
    pub fn set_or_clear_document<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Document>,
    {
        self.document = v.map(|x| x.into());
        self
    }

    /// Sets the value of [read_time][crate::model::RunQueryResponse::read_time].
    pub fn set_read_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.read_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [read_time][crate::model::RunQueryResponse::read_time].
    pub fn set_or_clear_read_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.read_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [skipped_results][crate::model::RunQueryResponse::skipped_results].
    pub fn set_skipped_results<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.skipped_results = v.into();
        self
    }

    /// Sets the value of [explain_metrics][crate::model::RunQueryResponse::explain_metrics].
    pub fn set_explain_metrics<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::ExplainMetrics>,
    {
        self.explain_metrics = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [explain_metrics][crate::model::RunQueryResponse::explain_metrics].
    pub fn set_or_clear_explain_metrics<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::ExplainMetrics>,
    {
        self.explain_metrics = v.map(|x| x.into());
        self
    }

    /// Sets the value of [continuation_selector][crate::model::RunQueryResponse::continuation_selector].
    ///
    /// Note that all the setters affecting `continuation_selector` are mutually
    /// exclusive.
    pub fn set_continuation_selector<
        T: std::convert::Into<
                std::option::Option<crate::model::run_query_response::ContinuationSelector>,
            >,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.continuation_selector = v.into();
        self
    }

    /// The value of [continuation_selector][crate::model::RunQueryResponse::continuation_selector]
    /// if it holds a `Done`, `None` if the field is not set or
    /// holds a different branch.
    pub fn done(&self) -> std::option::Option<&bool> {
        #[allow(unreachable_patterns)]
        self.continuation_selector.as_ref().and_then(|v| match v {
            crate::model::run_query_response::ContinuationSelector::Done(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [continuation_selector][crate::model::RunQueryResponse::continuation_selector]
    /// to hold a `Done`.
    ///
    /// Note that all the setters affecting `continuation_selector` are
    /// mutually exclusive.
    pub fn set_done<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.continuation_selector = std::option::Option::Some(
            crate::model::run_query_response::ContinuationSelector::Done(v.into()),
        );
        self
    }
}

impl wkt::message::Message for RunQueryResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.RunQueryResponse"
    }
}

/// Defines additional types related to [RunQueryResponse].
pub mod run_query_response {
    #[allow(unused_imports)]
    use super::*;

    /// The continuation mode for the query. If present, it indicates the current
    /// query response stream has finished. This can be set with or without a
    /// `document` present, but when set, no more results are returned.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum ContinuationSelector {
        /// If present, Firestore has completely finished the request and no more
        /// documents will be returned.
        Done(bool),
    }

    impl ContinuationSelector {
        /// Initializes the enum to the [Done](Self::Done) branch.
        pub fn from_done(value: impl std::convert::Into<bool>) -> Self {
            Self::Done(value.into())
        }
    }
}

/// The request for
/// [Firestore.RunAggregationQuery][google.firestore.v1.Firestore.RunAggregationQuery].
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct RunAggregationQueryRequest {
    /// Required. The parent resource name. In the format:
    /// `projects/{project_id}/databases/{database_id}/documents` or
    /// `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
    /// For example:
    /// `projects/my-project/databases/my-database/documents` or
    /// `projects/my-project/databases/my-database/documents/chatrooms/my-chatroom`
    pub parent: std::string::String,

    /// Optional. Explain options for the query. If set, additional query
    /// statistics will be returned. If not, only query results will be returned.
    pub explain_options: std::option::Option<crate::model::ExplainOptions>,

    /// The query to run.
    pub query_type: std::option::Option<crate::model::run_aggregation_query_request::QueryType>,

    /// The consistency mode for the query, defaults to strong consistency.
    pub consistency_selector:
        std::option::Option<crate::model::run_aggregation_query_request::ConsistencySelector>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl RunAggregationQueryRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::RunAggregationQueryRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [explain_options][crate::model::RunAggregationQueryRequest::explain_options].
    pub fn set_explain_options<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::ExplainOptions>,
    {
        self.explain_options = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [explain_options][crate::model::RunAggregationQueryRequest::explain_options].
    pub fn set_or_clear_explain_options<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::ExplainOptions>,
    {
        self.explain_options = v.map(|x| x.into());
        self
    }

    /// Sets the value of [query_type][crate::model::RunAggregationQueryRequest::query_type].
    ///
    /// Note that all the setters affecting `query_type` are mutually
    /// exclusive.
    pub fn set_query_type<
        T: std::convert::Into<
                std::option::Option<crate::model::run_aggregation_query_request::QueryType>,
            >,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.query_type = v.into();
        self
    }

    /// The value of [query_type][crate::model::RunAggregationQueryRequest::query_type]
    /// if it holds a `StructuredAggregationQuery`, `None` if the field is not set or
    /// holds a different branch.
    pub fn structured_aggregation_query(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::StructuredAggregationQuery>> {
        #[allow(unreachable_patterns)]
        self.query_type.as_ref().and_then(|v| match v {
            crate::model::run_aggregation_query_request::QueryType::StructuredAggregationQuery(
                v,
            ) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [query_type][crate::model::RunAggregationQueryRequest::query_type]
    /// to hold a `StructuredAggregationQuery`.
    ///
    /// Note that all the setters affecting `query_type` are
    /// mutually exclusive.
    pub fn set_structured_aggregation_query<
        T: std::convert::Into<std::boxed::Box<crate::model::StructuredAggregationQuery>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.query_type = std::option::Option::Some(
            crate::model::run_aggregation_query_request::QueryType::StructuredAggregationQuery(
                v.into(),
            ),
        );
        self
    }

    /// Sets the value of [consistency_selector][crate::model::RunAggregationQueryRequest::consistency_selector].
    ///
    /// Note that all the setters affecting `consistency_selector` are mutually
    /// exclusive.
    pub fn set_consistency_selector<
        T: std::convert::Into<
                std::option::Option<
                    crate::model::run_aggregation_query_request::ConsistencySelector,
                >,
            >,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.consistency_selector = v.into();
        self
    }

    /// The value of [consistency_selector][crate::model::RunAggregationQueryRequest::consistency_selector]
    /// if it holds a `Transaction`, `None` if the field is not set or
    /// holds a different branch.
    pub fn transaction(&self) -> std::option::Option<&::bytes::Bytes> {
        #[allow(unreachable_patterns)]
        self.consistency_selector.as_ref().and_then(|v| match v {
            crate::model::run_aggregation_query_request::ConsistencySelector::Transaction(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [consistency_selector][crate::model::RunAggregationQueryRequest::consistency_selector]
    /// to hold a `Transaction`.
    ///
    /// Note that all the setters affecting `consistency_selector` are
    /// mutually exclusive.
    pub fn set_transaction<T: std::convert::Into<::bytes::Bytes>>(mut self, v: T) -> Self {
        self.consistency_selector = std::option::Option::Some(
            crate::model::run_aggregation_query_request::ConsistencySelector::Transaction(v.into()),
        );
        self
    }

    /// The value of [consistency_selector][crate::model::RunAggregationQueryRequest::consistency_selector]
    /// if it holds a `NewTransaction`, `None` if the field is not set or
    /// holds a different branch.
    pub fn new_transaction(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::TransactionOptions>> {
        #[allow(unreachable_patterns)]
        self.consistency_selector.as_ref().and_then(|v| match v {
            crate::model::run_aggregation_query_request::ConsistencySelector::NewTransaction(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [consistency_selector][crate::model::RunAggregationQueryRequest::consistency_selector]
    /// to hold a `NewTransaction`.
    ///
    /// Note that all the setters affecting `consistency_selector` are
    /// mutually exclusive.
    pub fn set_new_transaction<
        T: std::convert::Into<std::boxed::Box<crate::model::TransactionOptions>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.consistency_selector = std::option::Option::Some(
            crate::model::run_aggregation_query_request::ConsistencySelector::NewTransaction(
                v.into(),
            ),
        );
        self
    }

    /// The value of [consistency_selector][crate::model::RunAggregationQueryRequest::consistency_selector]
    /// if it holds a `ReadTime`, `None` if the field is not set or
    /// holds a different branch.
    pub fn read_time(&self) -> std::option::Option<&std::boxed::Box<wkt::Timestamp>> {
        #[allow(unreachable_patterns)]
        self.consistency_selector.as_ref().and_then(|v| match v {
            crate::model::run_aggregation_query_request::ConsistencySelector::ReadTime(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [consistency_selector][crate::model::RunAggregationQueryRequest::consistency_selector]
    /// to hold a `ReadTime`.
    ///
    /// Note that all the setters affecting `consistency_selector` are
    /// mutually exclusive.
    pub fn set_read_time<T: std::convert::Into<std::boxed::Box<wkt::Timestamp>>>(
        mut self,
        v: T,
    ) -> Self {
        self.consistency_selector = std::option::Option::Some(
            crate::model::run_aggregation_query_request::ConsistencySelector::ReadTime(v.into()),
        );
        self
    }
}

impl wkt::message::Message for RunAggregationQueryRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.RunAggregationQueryRequest"
    }
}

/// Defines additional types related to [RunAggregationQueryRequest].
pub mod run_aggregation_query_request {
    #[allow(unused_imports)]
    use super::*;

    /// The query to run.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum QueryType {
        /// An aggregation query.
        StructuredAggregationQuery(std::boxed::Box<crate::model::StructuredAggregationQuery>),
    }

    impl QueryType {
        /// Initializes the enum to the [StructuredAggregationQuery](Self::StructuredAggregationQuery) branch.
        pub fn from_structured_aggregation_query(
            value: impl std::convert::Into<std::boxed::Box<crate::model::StructuredAggregationQuery>>,
        ) -> Self {
            Self::StructuredAggregationQuery(value.into())
        }
    }

    /// The consistency mode for the query, defaults to strong consistency.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum ConsistencySelector {
        /// Run the aggregation within an already active transaction.
        ///
        /// The value here is the opaque transaction ID to execute the query in.
        Transaction(::bytes::Bytes),
        /// Starts a new transaction as part of the query, defaulting to read-only.
        ///
        /// The new transaction ID will be returned as the first response in the
        /// stream.
        NewTransaction(std::boxed::Box<crate::model::TransactionOptions>),
        /// Executes the query at the given timestamp.
        ///
        /// This must be a microsecond precision timestamp within the past one hour,
        /// or if Point-in-Time Recovery is enabled, can additionally be a whole
        /// minute timestamp within the past 7 days.
        ReadTime(std::boxed::Box<wkt::Timestamp>),
    }

    impl ConsistencySelector {
        /// Initializes the enum to the [Transaction](Self::Transaction) branch.
        pub fn from_transaction(value: impl std::convert::Into<::bytes::Bytes>) -> Self {
            Self::Transaction(value.into())
        }
        /// Initializes the enum to the [NewTransaction](Self::NewTransaction) branch.
        pub fn from_new_transaction(
            value: impl std::convert::Into<std::boxed::Box<crate::model::TransactionOptions>>,
        ) -> Self {
            Self::NewTransaction(value.into())
        }
        /// Initializes the enum to the [ReadTime](Self::ReadTime) branch.
        pub fn from_read_time(
            value: impl std::convert::Into<std::boxed::Box<wkt::Timestamp>>,
        ) -> Self {
            Self::ReadTime(value.into())
        }
    }
}

/// The response for
/// [Firestore.RunAggregationQuery][google.firestore.v1.Firestore.RunAggregationQuery].
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct RunAggregationQueryResponse {
    /// A single aggregation result.
    ///
    /// Not present when reporting partial progress.
    pub result: std::option::Option<crate::model::AggregationResult>,

    /// The transaction that was started as part of this request.
    ///
    /// Only present on the first response when the request requested to start
    /// a new transaction.
    pub transaction: ::bytes::Bytes,

    /// The time at which the aggregate result was computed. This is always
    /// monotonically increasing; in this case, the previous AggregationResult in
    /// the result stream are guaranteed not to have changed between their
    /// `read_time` and this one.
    ///
    /// If the query returns no results, a response with `read_time` and no
    /// `result` will be sent, and this represents the time at which the query
    /// was run.
    pub read_time: std::option::Option<wkt::Timestamp>,

    /// Query explain metrics. This is only present when the
    /// [RunAggregationQueryRequest.explain_options][google.firestore.v1.RunAggregationQueryRequest.explain_options]
    /// is provided, and it is sent only once with the last response in the stream.
    ///
    /// [google.firestore.v1.RunAggregationQueryRequest.explain_options]: crate::model::RunAggregationQueryRequest::explain_options
    pub explain_metrics: std::option::Option<crate::model::ExplainMetrics>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl RunAggregationQueryResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [result][crate::model::RunAggregationQueryResponse::result].
    pub fn set_result<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::AggregationResult>,
    {
        self.result = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [result][crate::model::RunAggregationQueryResponse::result].
    pub fn set_or_clear_result<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::AggregationResult>,
    {
        self.result = v.map(|x| x.into());
        self
    }

    /// Sets the value of [transaction][crate::model::RunAggregationQueryResponse::transaction].
    pub fn set_transaction<T: std::convert::Into<::bytes::Bytes>>(mut self, v: T) -> Self {
        self.transaction = v.into();
        self
    }

    /// Sets the value of [read_time][crate::model::RunAggregationQueryResponse::read_time].
    pub fn set_read_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.read_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [read_time][crate::model::RunAggregationQueryResponse::read_time].
    pub fn set_or_clear_read_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.read_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [explain_metrics][crate::model::RunAggregationQueryResponse::explain_metrics].
    pub fn set_explain_metrics<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::ExplainMetrics>,
    {
        self.explain_metrics = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [explain_metrics][crate::model::RunAggregationQueryResponse::explain_metrics].
    pub fn set_or_clear_explain_metrics<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::ExplainMetrics>,
    {
        self.explain_metrics = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for RunAggregationQueryResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.RunAggregationQueryResponse"
    }
}

/// The request for
/// [Firestore.PartitionQuery][google.firestore.v1.Firestore.PartitionQuery].
///
/// [google.firestore.v1.Firestore.PartitionQuery]: crate::client::Firestore::partition_query
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct PartitionQueryRequest {
    /// Required. The parent resource name. In the format:
    /// `projects/{project_id}/databases/{database_id}/documents`.
    /// Document resource names are not supported; only database resource names
    /// can be specified.
    pub parent: std::string::String,

    /// The desired maximum number of partition points.
    /// The partitions may be returned across multiple pages of results.
    /// The number must be positive. The actual number of partitions
    /// returned may be fewer.
    ///
    /// For example, this may be set to one fewer than the number of parallel
    /// queries to be run, or in running a data pipeline job, one fewer than the
    /// number of workers or compute instances available.
    pub partition_count: i64,

    /// The `next_page_token` value returned from a previous call to
    /// PartitionQuery that may be used to get an additional set of results.
    /// There are no ordering guarantees between sets of results. Thus, using
    /// multiple sets of results will require merging the different result sets.
    ///
    /// For example, two subsequent calls using a page_token may return:
    ///
    /// * cursor B, cursor M, cursor Q
    /// * cursor A, cursor U, cursor W
    ///
    /// To obtain a complete result set ordered with respect to the results of the
    /// query supplied to PartitionQuery, the results sets should be merged:
    /// cursor A, cursor B, cursor M, cursor Q, cursor U, cursor W
    pub page_token: std::string::String,

    /// The maximum number of partitions to return in this call, subject to
    /// `partition_count`.
    ///
    /// For example, if `partition_count` = 10 and `page_size` = 8, the first call
    /// to PartitionQuery will return up to 8 partitions and a `next_page_token`
    /// if more results exist. A second call to PartitionQuery will return up to
    /// 2 partitions, to complete the total of 10 specified in `partition_count`.
    pub page_size: i32,

    /// The query to partition.
    pub query_type: std::option::Option<crate::model::partition_query_request::QueryType>,

    /// The consistency mode for this request.
    /// If not set, defaults to strong consistency.
    pub consistency_selector:
        std::option::Option<crate::model::partition_query_request::ConsistencySelector>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl PartitionQueryRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::PartitionQueryRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [partition_count][crate::model::PartitionQueryRequest::partition_count].
    pub fn set_partition_count<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
        self.partition_count = v.into();
        self
    }

    /// Sets the value of [page_token][crate::model::PartitionQueryRequest::page_token].
    pub fn set_page_token<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.page_token = v.into();
        self
    }

    /// Sets the value of [page_size][crate::model::PartitionQueryRequest::page_size].
    pub fn set_page_size<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.page_size = v.into();
        self
    }

    /// Sets the value of [query_type][crate::model::PartitionQueryRequest::query_type].
    ///
    /// Note that all the setters affecting `query_type` are mutually
    /// exclusive.
    pub fn set_query_type<
        T: std::convert::Into<std::option::Option<crate::model::partition_query_request::QueryType>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.query_type = v.into();
        self
    }

    /// The value of [query_type][crate::model::PartitionQueryRequest::query_type]
    /// if it holds a `StructuredQuery`, `None` if the field is not set or
    /// holds a different branch.
    pub fn structured_query(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::StructuredQuery>> {
        #[allow(unreachable_patterns)]
        self.query_type.as_ref().and_then(|v| match v {
            crate::model::partition_query_request::QueryType::StructuredQuery(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [query_type][crate::model::PartitionQueryRequest::query_type]
    /// to hold a `StructuredQuery`.
    ///
    /// Note that all the setters affecting `query_type` are
    /// mutually exclusive.
    pub fn set_structured_query<
        T: std::convert::Into<std::boxed::Box<crate::model::StructuredQuery>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.query_type = std::option::Option::Some(
            crate::model::partition_query_request::QueryType::StructuredQuery(v.into()),
        );
        self
    }

    /// Sets the value of [consistency_selector][crate::model::PartitionQueryRequest::consistency_selector].
    ///
    /// Note that all the setters affecting `consistency_selector` are mutually
    /// exclusive.
    pub fn set_consistency_selector<
        T: std::convert::Into<
                std::option::Option<crate::model::partition_query_request::ConsistencySelector>,
            >,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.consistency_selector = v.into();
        self
    }

    /// The value of [consistency_selector][crate::model::PartitionQueryRequest::consistency_selector]
    /// if it holds a `ReadTime`, `None` if the field is not set or
    /// holds a different branch.
    pub fn read_time(&self) -> std::option::Option<&std::boxed::Box<wkt::Timestamp>> {
        #[allow(unreachable_patterns)]
        self.consistency_selector.as_ref().and_then(|v| match v {
            crate::model::partition_query_request::ConsistencySelector::ReadTime(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [consistency_selector][crate::model::PartitionQueryRequest::consistency_selector]
    /// to hold a `ReadTime`.
    ///
    /// Note that all the setters affecting `consistency_selector` are
    /// mutually exclusive.
    pub fn set_read_time<T: std::convert::Into<std::boxed::Box<wkt::Timestamp>>>(
        mut self,
        v: T,
    ) -> Self {
        self.consistency_selector = std::option::Option::Some(
            crate::model::partition_query_request::ConsistencySelector::ReadTime(v.into()),
        );
        self
    }
}

impl wkt::message::Message for PartitionQueryRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.PartitionQueryRequest"
    }
}

/// Defines additional types related to [PartitionQueryRequest].
pub mod partition_query_request {
    #[allow(unused_imports)]
    use super::*;

    /// The query to partition.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum QueryType {
        /// A structured query.
        /// Query must specify collection with all descendants and be ordered by name
        /// ascending. Other filters, order bys, limits, offsets, and start/end
        /// cursors are not supported.
        StructuredQuery(std::boxed::Box<crate::model::StructuredQuery>),
    }

    impl QueryType {
        /// Initializes the enum to the [StructuredQuery](Self::StructuredQuery) branch.
        pub fn from_structured_query(
            value: impl std::convert::Into<std::boxed::Box<crate::model::StructuredQuery>>,
        ) -> Self {
            Self::StructuredQuery(value.into())
        }
    }

    /// The consistency mode for this request.
    /// If not set, defaults to strong consistency.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum ConsistencySelector {
        /// Reads documents as they were at the given time.
        ///
        /// This must be a microsecond precision timestamp within the past one hour,
        /// or if Point-in-Time Recovery is enabled, can additionally be a whole
        /// minute timestamp within the past 7 days.
        ReadTime(std::boxed::Box<wkt::Timestamp>),
    }

    impl ConsistencySelector {
        /// Initializes the enum to the [ReadTime](Self::ReadTime) branch.
        pub fn from_read_time(
            value: impl std::convert::Into<std::boxed::Box<wkt::Timestamp>>,
        ) -> Self {
            Self::ReadTime(value.into())
        }
    }
}

/// The response for
/// [Firestore.PartitionQuery][google.firestore.v1.Firestore.PartitionQuery].
///
/// [google.firestore.v1.Firestore.PartitionQuery]: crate::client::Firestore::partition_query
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct PartitionQueryResponse {
    /// Partition results.
    /// Each partition is a split point that can be used by RunQuery as a starting
    /// or end point for the query results. The RunQuery requests must be made with
    /// the same query supplied to this PartitionQuery request. The partition
    /// cursors will be ordered according to same ordering as the results of the
    /// query supplied to PartitionQuery.
    ///
    /// For example, if a PartitionQuery request returns partition cursors A and B,
    /// running the following three queries will return the entire result set of
    /// the original query:
    ///
    /// * query, end_at A
    /// * query, start_at A, end_at B
    /// * query, start_at B
    ///
    /// An empty result may indicate that the query has too few results to be
    /// partitioned, or that the query is not yet supported for partitioning.
    pub partitions: std::vec::Vec<crate::model::Cursor>,

    /// A page token that may be used to request an additional set of results, up
    /// to the number specified by `partition_count` in the PartitionQuery request.
    /// If blank, there are no more results.
    pub next_page_token: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl PartitionQueryResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [partitions][crate::model::PartitionQueryResponse::partitions].
    pub fn set_partitions<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::Cursor>,
    {
        use std::iter::Iterator;
        self.partitions = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [next_page_token][crate::model::PartitionQueryResponse::next_page_token].
    pub fn set_next_page_token<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.next_page_token = v.into();
        self
    }
}

impl wkt::message::Message for PartitionQueryResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.PartitionQueryResponse"
    }
}

#[doc(hidden)]
impl gax::paginator::internal::PageableResponse for PartitionQueryResponse {
    type PageItem = crate::model::Cursor;

    fn items(self) -> std::vec::Vec<Self::PageItem> {
        self.partitions
    }

    fn next_page_token(&self) -> std::string::String {
        use std::clone::Clone;
        self.next_page_token.clone()
    }
}

/// The request for [Firestore.Write][google.firestore.v1.Firestore.Write].
///
/// The first request creates a stream, or resumes an existing one from a token.
///
/// When creating a new stream, the server replies with a response containing
/// only an ID and a token, to use in the next request.
///
/// When resuming a stream, the server first streams any responses later than the
/// given token, then a response containing only an up-to-date token, to use in
/// the next request.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct WriteRequest {
    /// Required. The database name. In the format:
    /// `projects/{project_id}/databases/{database_id}`.
    /// This is only required in the first message.
    pub database: std::string::String,

    /// The ID of the write stream to resume.
    /// This may only be set in the first message. When left empty, a new write
    /// stream will be created.
    pub stream_id: std::string::String,

    /// The writes to apply.
    ///
    /// Always executed atomically and in order.
    /// This must be empty on the first request.
    /// This may be empty on the last request.
    /// This must not be empty on all other requests.
    pub writes: std::vec::Vec<crate::model::Write>,

    /// A stream token that was previously sent by the server.
    ///
    /// The client should set this field to the token from the most recent
    /// [WriteResponse][google.firestore.v1.WriteResponse] it has received. This
    /// acknowledges that the client has received responses up to this token. After
    /// sending this token, earlier tokens may not be used anymore.
    ///
    /// The server may close the stream if there are too many unacknowledged
    /// responses.
    ///
    /// Leave this field unset when creating a new stream. To resume a stream at
    /// a specific point, set this field and the `stream_id` field.
    ///
    /// Leave this field unset when creating a new stream.
    ///
    /// [google.firestore.v1.WriteResponse]: crate::model::WriteResponse
    pub stream_token: ::bytes::Bytes,

    /// Labels associated with this write request.
    pub labels: std::collections::HashMap<std::string::String, std::string::String>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl WriteRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [database][crate::model::WriteRequest::database].
    pub fn set_database<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.database = v.into();
        self
    }

    /// Sets the value of [stream_id][crate::model::WriteRequest::stream_id].
    pub fn set_stream_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.stream_id = v.into();
        self
    }

    /// Sets the value of [writes][crate::model::WriteRequest::writes].
    pub fn set_writes<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::Write>,
    {
        use std::iter::Iterator;
        self.writes = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [stream_token][crate::model::WriteRequest::stream_token].
    pub fn set_stream_token<T: std::convert::Into<::bytes::Bytes>>(mut self, v: T) -> Self {
        self.stream_token = v.into();
        self
    }

    /// Sets the value of [labels][crate::model::WriteRequest::labels].
    pub fn set_labels<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.labels = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }
}

impl wkt::message::Message for WriteRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.WriteRequest"
    }
}

/// The response for [Firestore.Write][google.firestore.v1.Firestore.Write].
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct WriteResponse {
    /// The ID of the stream.
    /// Only set on the first message, when a new stream was created.
    pub stream_id: std::string::String,

    /// A token that represents the position of this response in the stream.
    /// This can be used by a client to resume the stream at this point.
    ///
    /// This field is always set.
    pub stream_token: ::bytes::Bytes,

    /// The result of applying the writes.
    ///
    /// This i-th write result corresponds to the i-th write in the
    /// request.
    pub write_results: std::vec::Vec<crate::model::WriteResult>,

    /// The time at which the commit occurred. Any read with an equal or greater
    /// `read_time` is guaranteed to see the effects of the write.
    pub commit_time: std::option::Option<wkt::Timestamp>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl WriteResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [stream_id][crate::model::WriteResponse::stream_id].
    pub fn set_stream_id<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.stream_id = v.into();
        self
    }

    /// Sets the value of [stream_token][crate::model::WriteResponse::stream_token].
    pub fn set_stream_token<T: std::convert::Into<::bytes::Bytes>>(mut self, v: T) -> Self {
        self.stream_token = v.into();
        self
    }

    /// Sets the value of [write_results][crate::model::WriteResponse::write_results].
    pub fn set_write_results<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::WriteResult>,
    {
        use std::iter::Iterator;
        self.write_results = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [commit_time][crate::model::WriteResponse::commit_time].
    pub fn set_commit_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.commit_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [commit_time][crate::model::WriteResponse::commit_time].
    pub fn set_or_clear_commit_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.commit_time = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for WriteResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.WriteResponse"
    }
}

/// A request for [Firestore.Listen][google.firestore.v1.Firestore.Listen]
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ListenRequest {
    /// Required. The database name. In the format:
    /// `projects/{project_id}/databases/{database_id}`.
    pub database: std::string::String,

    /// Labels associated with this target change.
    pub labels: std::collections::HashMap<std::string::String, std::string::String>,

    /// The supported target changes.
    pub target_change: std::option::Option<crate::model::listen_request::TargetChange>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ListenRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [database][crate::model::ListenRequest::database].
    pub fn set_database<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.database = v.into();
        self
    }

    /// Sets the value of [labels][crate::model::ListenRequest::labels].
    pub fn set_labels<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.labels = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }

    /// Sets the value of [target_change][crate::model::ListenRequest::target_change].
    ///
    /// Note that all the setters affecting `target_change` are mutually
    /// exclusive.
    pub fn set_target_change<
        T: std::convert::Into<std::option::Option<crate::model::listen_request::TargetChange>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.target_change = v.into();
        self
    }

    /// The value of [target_change][crate::model::ListenRequest::target_change]
    /// if it holds a `AddTarget`, `None` if the field is not set or
    /// holds a different branch.
    pub fn add_target(&self) -> std::option::Option<&std::boxed::Box<crate::model::Target>> {
        #[allow(unreachable_patterns)]
        self.target_change.as_ref().and_then(|v| match v {
            crate::model::listen_request::TargetChange::AddTarget(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [target_change][crate::model::ListenRequest::target_change]
    /// to hold a `AddTarget`.
    ///
    /// Note that all the setters affecting `target_change` are
    /// mutually exclusive.
    pub fn set_add_target<T: std::convert::Into<std::boxed::Box<crate::model::Target>>>(
        mut self,
        v: T,
    ) -> Self {
        self.target_change = std::option::Option::Some(
            crate::model::listen_request::TargetChange::AddTarget(v.into()),
        );
        self
    }

    /// The value of [target_change][crate::model::ListenRequest::target_change]
    /// if it holds a `RemoveTarget`, `None` if the field is not set or
    /// holds a different branch.
    pub fn remove_target(&self) -> std::option::Option<&i32> {
        #[allow(unreachable_patterns)]
        self.target_change.as_ref().and_then(|v| match v {
            crate::model::listen_request::TargetChange::RemoveTarget(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [target_change][crate::model::ListenRequest::target_change]
    /// to hold a `RemoveTarget`.
    ///
    /// Note that all the setters affecting `target_change` are
    /// mutually exclusive.
    pub fn set_remove_target<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.target_change = std::option::Option::Some(
            crate::model::listen_request::TargetChange::RemoveTarget(v.into()),
        );
        self
    }
}

impl wkt::message::Message for ListenRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.ListenRequest"
    }
}

/// Defines additional types related to [ListenRequest].
pub mod listen_request {
    #[allow(unused_imports)]
    use super::*;

    /// The supported target changes.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum TargetChange {
        /// A target to add to this stream.
        AddTarget(std::boxed::Box<crate::model::Target>),
        /// The ID of a target to remove from this stream.
        RemoveTarget(i32),
    }

    impl TargetChange {
        /// Initializes the enum to the [AddTarget](Self::AddTarget) branch.
        pub fn from_add_target(
            value: impl std::convert::Into<std::boxed::Box<crate::model::Target>>,
        ) -> Self {
            Self::AddTarget(value.into())
        }
        /// Initializes the enum to the [RemoveTarget](Self::RemoveTarget) branch.
        pub fn from_remove_target(value: impl std::convert::Into<i32>) -> Self {
            Self::RemoveTarget(value.into())
        }
    }
}

/// The response for [Firestore.Listen][google.firestore.v1.Firestore.Listen].
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ListenResponse {
    /// The supported responses.
    pub response_type: std::option::Option<crate::model::listen_response::ResponseType>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ListenResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [response_type][crate::model::ListenResponse::response_type].
    ///
    /// Note that all the setters affecting `response_type` are mutually
    /// exclusive.
    pub fn set_response_type<
        T: std::convert::Into<std::option::Option<crate::model::listen_response::ResponseType>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.response_type = v.into();
        self
    }

    /// The value of [response_type][crate::model::ListenResponse::response_type]
    /// if it holds a `TargetChange`, `None` if the field is not set or
    /// holds a different branch.
    pub fn target_change(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::TargetChange>> {
        #[allow(unreachable_patterns)]
        self.response_type.as_ref().and_then(|v| match v {
            crate::model::listen_response::ResponseType::TargetChange(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [response_type][crate::model::ListenResponse::response_type]
    /// to hold a `TargetChange`.
    ///
    /// Note that all the setters affecting `response_type` are
    /// mutually exclusive.
    pub fn set_target_change<T: std::convert::Into<std::boxed::Box<crate::model::TargetChange>>>(
        mut self,
        v: T,
    ) -> Self {
        self.response_type = std::option::Option::Some(
            crate::model::listen_response::ResponseType::TargetChange(v.into()),
        );
        self
    }

    /// The value of [response_type][crate::model::ListenResponse::response_type]
    /// if it holds a `DocumentChange`, `None` if the field is not set or
    /// holds a different branch.
    pub fn document_change(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::DocumentChange>> {
        #[allow(unreachable_patterns)]
        self.response_type.as_ref().and_then(|v| match v {
            crate::model::listen_response::ResponseType::DocumentChange(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [response_type][crate::model::ListenResponse::response_type]
    /// to hold a `DocumentChange`.
    ///
    /// Note that all the setters affecting `response_type` are
    /// mutually exclusive.
    pub fn set_document_change<
        T: std::convert::Into<std::boxed::Box<crate::model::DocumentChange>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.response_type = std::option::Option::Some(
            crate::model::listen_response::ResponseType::DocumentChange(v.into()),
        );
        self
    }

    /// The value of [response_type][crate::model::ListenResponse::response_type]
    /// if it holds a `DocumentDelete`, `None` if the field is not set or
    /// holds a different branch.
    pub fn document_delete(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::DocumentDelete>> {
        #[allow(unreachable_patterns)]
        self.response_type.as_ref().and_then(|v| match v {
            crate::model::listen_response::ResponseType::DocumentDelete(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [response_type][crate::model::ListenResponse::response_type]
    /// to hold a `DocumentDelete`.
    ///
    /// Note that all the setters affecting `response_type` are
    /// mutually exclusive.
    pub fn set_document_delete<
        T: std::convert::Into<std::boxed::Box<crate::model::DocumentDelete>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.response_type = std::option::Option::Some(
            crate::model::listen_response::ResponseType::DocumentDelete(v.into()),
        );
        self
    }

    /// The value of [response_type][crate::model::ListenResponse::response_type]
    /// if it holds a `DocumentRemove`, `None` if the field is not set or
    /// holds a different branch.
    pub fn document_remove(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::DocumentRemove>> {
        #[allow(unreachable_patterns)]
        self.response_type.as_ref().and_then(|v| match v {
            crate::model::listen_response::ResponseType::DocumentRemove(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [response_type][crate::model::ListenResponse::response_type]
    /// to hold a `DocumentRemove`.
    ///
    /// Note that all the setters affecting `response_type` are
    /// mutually exclusive.
    pub fn set_document_remove<
        T: std::convert::Into<std::boxed::Box<crate::model::DocumentRemove>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.response_type = std::option::Option::Some(
            crate::model::listen_response::ResponseType::DocumentRemove(v.into()),
        );
        self
    }

    /// The value of [response_type][crate::model::ListenResponse::response_type]
    /// if it holds a `Filter`, `None` if the field is not set or
    /// holds a different branch.
    pub fn filter(&self) -> std::option::Option<&std::boxed::Box<crate::model::ExistenceFilter>> {
        #[allow(unreachable_patterns)]
        self.response_type.as_ref().and_then(|v| match v {
            crate::model::listen_response::ResponseType::Filter(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [response_type][crate::model::ListenResponse::response_type]
    /// to hold a `Filter`.
    ///
    /// Note that all the setters affecting `response_type` are
    /// mutually exclusive.
    pub fn set_filter<T: std::convert::Into<std::boxed::Box<crate::model::ExistenceFilter>>>(
        mut self,
        v: T,
    ) -> Self {
        self.response_type = std::option::Option::Some(
            crate::model::listen_response::ResponseType::Filter(v.into()),
        );
        self
    }
}

impl wkt::message::Message for ListenResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.ListenResponse"
    }
}

/// Defines additional types related to [ListenResponse].
pub mod listen_response {
    #[allow(unused_imports)]
    use super::*;

    /// The supported responses.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum ResponseType {
        /// Targets have changed.
        TargetChange(std::boxed::Box<crate::model::TargetChange>),
        /// A [Document][google.firestore.v1.Document] has changed.
        ///
        /// [google.firestore.v1.Document]: crate::model::Document
        DocumentChange(std::boxed::Box<crate::model::DocumentChange>),
        /// A [Document][google.firestore.v1.Document] has been deleted.
        ///
        /// [google.firestore.v1.Document]: crate::model::Document
        DocumentDelete(std::boxed::Box<crate::model::DocumentDelete>),
        /// A [Document][google.firestore.v1.Document] has been removed from a target
        /// (because it is no longer relevant to that target).
        ///
        /// [google.firestore.v1.Document]: crate::model::Document
        DocumentRemove(std::boxed::Box<crate::model::DocumentRemove>),
        /// A filter to apply to the set of documents previously returned for the
        /// given target.
        ///
        /// Returned when documents may have been removed from the given target, but
        /// the exact documents are unknown.
        Filter(std::boxed::Box<crate::model::ExistenceFilter>),
    }

    impl ResponseType {
        /// Initializes the enum to the [TargetChange](Self::TargetChange) branch.
        pub fn from_target_change(
            value: impl std::convert::Into<std::boxed::Box<crate::model::TargetChange>>,
        ) -> Self {
            Self::TargetChange(value.into())
        }
        /// Initializes the enum to the [DocumentChange](Self::DocumentChange) branch.
        pub fn from_document_change(
            value: impl std::convert::Into<std::boxed::Box<crate::model::DocumentChange>>,
        ) -> Self {
            Self::DocumentChange(value.into())
        }
        /// Initializes the enum to the [DocumentDelete](Self::DocumentDelete) branch.
        pub fn from_document_delete(
            value: impl std::convert::Into<std::boxed::Box<crate::model::DocumentDelete>>,
        ) -> Self {
            Self::DocumentDelete(value.into())
        }
        /// Initializes the enum to the [DocumentRemove](Self::DocumentRemove) branch.
        pub fn from_document_remove(
            value: impl std::convert::Into<std::boxed::Box<crate::model::DocumentRemove>>,
        ) -> Self {
            Self::DocumentRemove(value.into())
        }
        /// Initializes the enum to the [Filter](Self::Filter) branch.
        pub fn from_filter(
            value: impl std::convert::Into<std::boxed::Box<crate::model::ExistenceFilter>>,
        ) -> Self {
            Self::Filter(value.into())
        }
    }
}

/// A specification of a set of documents to listen to.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Target {
    /// The target ID that identifies the target on the stream. Must be a positive
    /// number and non-zero.
    ///
    /// If `target_id` is 0 (or unspecified), the server will assign an ID for this
    /// target and return that in a `TargetChange::ADD` event. Once a target with
    /// `target_id=0` is added, all subsequent targets must also have
    /// `target_id=0`. If an `AddTarget` request with `target_id != 0` is
    /// sent to the server after a target with `target_id=0` is added, the server
    /// will immediately send a response with a `TargetChange::Remove` event.
    ///
    /// Note that if the client sends multiple `AddTarget` requests
    /// without an ID, the order of IDs returned in `TargetChange.target_ids` are
    /// undefined. Therefore, clients should provide a target ID instead of relying
    /// on the server to assign one.
    ///
    /// If `target_id` is non-zero, there must not be an existing active target on
    /// this stream with the same ID.
    pub target_id: i32,

    /// If the target should be removed once it is current and consistent.
    pub once: bool,

    /// The number of documents that last matched the query at the resume token or
    /// read time.
    ///
    /// This value is only relevant when a `resume_type` is provided. This value
    /// being present and greater than zero signals that the client wants
    /// `ExistenceFilter.unchanged_names` to be included in the response.
    pub expected_count: std::option::Option<wkt::Int32Value>,

    /// The type of target to listen to.
    pub target_type: std::option::Option<crate::model::target::TargetType>,

    /// When to start listening.
    ///
    /// If specified, only the matching Documents that have been updated AFTER the
    /// `resume_token` or `read_time` will be returned. Otherwise, all matching
    /// Documents are returned before any subsequent changes.
    pub resume_type: std::option::Option<crate::model::target::ResumeType>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Target {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [target_id][crate::model::Target::target_id].
    pub fn set_target_id<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.target_id = v.into();
        self
    }

    /// Sets the value of [once][crate::model::Target::once].
    pub fn set_once<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.once = v.into();
        self
    }

    /// Sets the value of [expected_count][crate::model::Target::expected_count].
    pub fn set_expected_count<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Int32Value>,
    {
        self.expected_count = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [expected_count][crate::model::Target::expected_count].
    pub fn set_or_clear_expected_count<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Int32Value>,
    {
        self.expected_count = v.map(|x| x.into());
        self
    }

    /// Sets the value of [target_type][crate::model::Target::target_type].
    ///
    /// Note that all the setters affecting `target_type` are mutually
    /// exclusive.
    pub fn set_target_type<
        T: std::convert::Into<std::option::Option<crate::model::target::TargetType>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.target_type = v.into();
        self
    }

    /// The value of [target_type][crate::model::Target::target_type]
    /// if it holds a `Query`, `None` if the field is not set or
    /// holds a different branch.
    pub fn query(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::target::QueryTarget>> {
        #[allow(unreachable_patterns)]
        self.target_type.as_ref().and_then(|v| match v {
            crate::model::target::TargetType::Query(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [target_type][crate::model::Target::target_type]
    /// to hold a `Query`.
    ///
    /// Note that all the setters affecting `target_type` are
    /// mutually exclusive.
    pub fn set_query<T: std::convert::Into<std::boxed::Box<crate::model::target::QueryTarget>>>(
        mut self,
        v: T,
    ) -> Self {
        self.target_type =
            std::option::Option::Some(crate::model::target::TargetType::Query(v.into()));
        self
    }

    /// The value of [target_type][crate::model::Target::target_type]
    /// if it holds a `Documents`, `None` if the field is not set or
    /// holds a different branch.
    pub fn documents(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::target::DocumentsTarget>> {
        #[allow(unreachable_patterns)]
        self.target_type.as_ref().and_then(|v| match v {
            crate::model::target::TargetType::Documents(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [target_type][crate::model::Target::target_type]
    /// to hold a `Documents`.
    ///
    /// Note that all the setters affecting `target_type` are
    /// mutually exclusive.
    pub fn set_documents<
        T: std::convert::Into<std::boxed::Box<crate::model::target::DocumentsTarget>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.target_type =
            std::option::Option::Some(crate::model::target::TargetType::Documents(v.into()));
        self
    }

    /// Sets the value of [resume_type][crate::model::Target::resume_type].
    ///
    /// Note that all the setters affecting `resume_type` are mutually
    /// exclusive.
    pub fn set_resume_type<
        T: std::convert::Into<std::option::Option<crate::model::target::ResumeType>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.resume_type = v.into();
        self
    }

    /// The value of [resume_type][crate::model::Target::resume_type]
    /// if it holds a `ResumeToken`, `None` if the field is not set or
    /// holds a different branch.
    pub fn resume_token(&self) -> std::option::Option<&::bytes::Bytes> {
        #[allow(unreachable_patterns)]
        self.resume_type.as_ref().and_then(|v| match v {
            crate::model::target::ResumeType::ResumeToken(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [resume_type][crate::model::Target::resume_type]
    /// to hold a `ResumeToken`.
    ///
    /// Note that all the setters affecting `resume_type` are
    /// mutually exclusive.
    pub fn set_resume_token<T: std::convert::Into<::bytes::Bytes>>(mut self, v: T) -> Self {
        self.resume_type =
            std::option::Option::Some(crate::model::target::ResumeType::ResumeToken(v.into()));
        self
    }

    /// The value of [resume_type][crate::model::Target::resume_type]
    /// if it holds a `ReadTime`, `None` if the field is not set or
    /// holds a different branch.
    pub fn read_time(&self) -> std::option::Option<&std::boxed::Box<wkt::Timestamp>> {
        #[allow(unreachable_patterns)]
        self.resume_type.as_ref().and_then(|v| match v {
            crate::model::target::ResumeType::ReadTime(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [resume_type][crate::model::Target::resume_type]
    /// to hold a `ReadTime`.
    ///
    /// Note that all the setters affecting `resume_type` are
    /// mutually exclusive.
    pub fn set_read_time<T: std::convert::Into<std::boxed::Box<wkt::Timestamp>>>(
        mut self,
        v: T,
    ) -> Self {
        self.resume_type =
            std::option::Option::Some(crate::model::target::ResumeType::ReadTime(v.into()));
        self
    }
}

impl wkt::message::Message for Target {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.Target"
    }
}

/// Defines additional types related to [Target].
pub mod target {
    #[allow(unused_imports)]
    use super::*;

    /// A target specified by a set of documents names.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct DocumentsTarget {
        /// The names of the documents to retrieve. In the format:
        /// `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
        /// The request will fail if any of the document is not a child resource of
        /// the given `database`. Duplicate names will be elided.
        pub documents: std::vec::Vec<std::string::String>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl DocumentsTarget {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [documents][crate::model::target::DocumentsTarget::documents].
        pub fn set_documents<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<std::string::String>,
        {
            use std::iter::Iterator;
            self.documents = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for DocumentsTarget {
        fn typename() -> &'static str {
            "type.googleapis.com/google.firestore.v1.Target.DocumentsTarget"
        }
    }

    /// A target specified by a query.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct QueryTarget {
        /// The parent resource name. In the format:
        /// `projects/{project_id}/databases/{database_id}/documents` or
        /// `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
        /// For example:
        /// `projects/my-project/databases/my-database/documents` or
        /// `projects/my-project/databases/my-database/documents/chatrooms/my-chatroom`
        pub parent: std::string::String,

        /// The query to run.
        pub query_type: std::option::Option<crate::model::target::query_target::QueryType>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl QueryTarget {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [parent][crate::model::target::QueryTarget::parent].
        pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.parent = v.into();
            self
        }

        /// Sets the value of [query_type][crate::model::target::QueryTarget::query_type].
        ///
        /// Note that all the setters affecting `query_type` are mutually
        /// exclusive.
        pub fn set_query_type<
            T: std::convert::Into<std::option::Option<crate::model::target::query_target::QueryType>>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.query_type = v.into();
            self
        }

        /// The value of [query_type][crate::model::target::QueryTarget::query_type]
        /// if it holds a `StructuredQuery`, `None` if the field is not set or
        /// holds a different branch.
        pub fn structured_query(
            &self,
        ) -> std::option::Option<&std::boxed::Box<crate::model::StructuredQuery>> {
            #[allow(unreachable_patterns)]
            self.query_type.as_ref().and_then(|v| match v {
                crate::model::target::query_target::QueryType::StructuredQuery(v) => {
                    std::option::Option::Some(v)
                }
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [query_type][crate::model::target::QueryTarget::query_type]
        /// to hold a `StructuredQuery`.
        ///
        /// Note that all the setters affecting `query_type` are
        /// mutually exclusive.
        pub fn set_structured_query<
            T: std::convert::Into<std::boxed::Box<crate::model::StructuredQuery>>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.query_type = std::option::Option::Some(
                crate::model::target::query_target::QueryType::StructuredQuery(v.into()),
            );
            self
        }
    }

    impl wkt::message::Message for QueryTarget {
        fn typename() -> &'static str {
            "type.googleapis.com/google.firestore.v1.Target.QueryTarget"
        }
    }

    /// Defines additional types related to [QueryTarget].
    pub mod query_target {
        #[allow(unused_imports)]
        use super::*;

        /// The query to run.
        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum QueryType {
            /// A structured query.
            StructuredQuery(std::boxed::Box<crate::model::StructuredQuery>),
        }

        impl QueryType {
            /// Initializes the enum to the [StructuredQuery](Self::StructuredQuery) branch.
            pub fn from_structured_query(
                value: impl std::convert::Into<std::boxed::Box<crate::model::StructuredQuery>>,
            ) -> Self {
                Self::StructuredQuery(value.into())
            }
        }
    }

    /// The type of target to listen to.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum TargetType {
        /// A target specified by a query.
        Query(std::boxed::Box<crate::model::target::QueryTarget>),
        /// A target specified by a set of document names.
        Documents(std::boxed::Box<crate::model::target::DocumentsTarget>),
    }

    impl TargetType {
        /// Initializes the enum to the [Query](Self::Query) branch.
        pub fn from_query(
            value: impl std::convert::Into<std::boxed::Box<crate::model::target::QueryTarget>>,
        ) -> Self {
            Self::Query(value.into())
        }
        /// Initializes the enum to the [Documents](Self::Documents) branch.
        pub fn from_documents(
            value: impl std::convert::Into<std::boxed::Box<crate::model::target::DocumentsTarget>>,
        ) -> Self {
            Self::Documents(value.into())
        }
    }

    /// When to start listening.
    ///
    /// If specified, only the matching Documents that have been updated AFTER the
    /// `resume_token` or `read_time` will be returned. Otherwise, all matching
    /// Documents are returned before any subsequent changes.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum ResumeType {
        /// A resume token from a prior
        /// [TargetChange][google.firestore.v1.TargetChange] for an identical target.
        ///
        /// Using a resume token with a different target is unsupported and may fail.
        ///
        /// [google.firestore.v1.TargetChange]: crate::model::TargetChange
        ResumeToken(::bytes::Bytes),
        /// Start listening after a specific `read_time`.
        ///
        /// The client must know the state of matching documents at this time.
        ReadTime(std::boxed::Box<wkt::Timestamp>),
    }

    impl ResumeType {
        /// Initializes the enum to the [ResumeToken](Self::ResumeToken) branch.
        pub fn from_resume_token(value: impl std::convert::Into<::bytes::Bytes>) -> Self {
            Self::ResumeToken(value.into())
        }
        /// Initializes the enum to the [ReadTime](Self::ReadTime) branch.
        pub fn from_read_time(
            value: impl std::convert::Into<std::boxed::Box<wkt::Timestamp>>,
        ) -> Self {
            Self::ReadTime(value.into())
        }
    }
}

/// Targets being watched have changed.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct TargetChange {
    /// The type of change that occurred.
    pub target_change_type: crate::model::target_change::TargetChangeType,

    /// The target IDs of targets that have changed.
    ///
    /// If empty, the change applies to all targets.
    ///
    /// The order of the target IDs is not defined.
    pub target_ids: std::vec::Vec<i32>,

    /// The error that resulted in this change, if applicable.
    pub cause: std::option::Option<rpc::model::Status>,

    /// A token that can be used to resume the stream for the given `target_ids`,
    /// or all targets if `target_ids` is empty.
    ///
    /// Not set on every target change.
    pub resume_token: ::bytes::Bytes,

    /// The consistent `read_time` for the given `target_ids` (omitted when the
    /// target_ids are not at a consistent snapshot).
    ///
    /// The stream is guaranteed to send a `read_time` with `target_ids` empty
    /// whenever the entire stream reaches a new consistent snapshot. ADD,
    /// CURRENT, and RESET messages are guaranteed to (eventually) result in a
    /// new consistent snapshot (while NO_CHANGE and REMOVE messages are not).
    ///
    /// For a given stream, `read_time` is guaranteed to be monotonically
    /// increasing.
    pub read_time: std::option::Option<wkt::Timestamp>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl TargetChange {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [target_change_type][crate::model::TargetChange::target_change_type].
    pub fn set_target_change_type<
        T: std::convert::Into<crate::model::target_change::TargetChangeType>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.target_change_type = v.into();
        self
    }

    /// Sets the value of [target_ids][crate::model::TargetChange::target_ids].
    pub fn set_target_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<i32>,
    {
        use std::iter::Iterator;
        self.target_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [cause][crate::model::TargetChange::cause].
    pub fn set_cause<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<rpc::model::Status>,
    {
        self.cause = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [cause][crate::model::TargetChange::cause].
    pub fn set_or_clear_cause<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<rpc::model::Status>,
    {
        self.cause = v.map(|x| x.into());
        self
    }

    /// Sets the value of [resume_token][crate::model::TargetChange::resume_token].
    pub fn set_resume_token<T: std::convert::Into<::bytes::Bytes>>(mut self, v: T) -> Self {
        self.resume_token = v.into();
        self
    }

    /// Sets the value of [read_time][crate::model::TargetChange::read_time].
    pub fn set_read_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.read_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [read_time][crate::model::TargetChange::read_time].
    pub fn set_or_clear_read_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.read_time = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for TargetChange {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.TargetChange"
    }
}

/// Defines additional types related to [TargetChange].
pub mod target_change {
    #[allow(unused_imports)]
    use super::*;

    /// The type of change.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum TargetChangeType {
        /// No change has occurred. Used only to send an updated `resume_token`.
        NoChange,
        /// The targets have been added.
        Add,
        /// The targets have been removed.
        Remove,
        /// The targets reflect all changes committed before the targets were added
        /// to the stream.
        ///
        /// This will be sent after or with a `read_time` that is greater than or
        /// equal to the time at which the targets were added.
        ///
        /// Listeners can wait for this change if read-after-write semantics
        /// are desired.
        Current,
        /// The targets have been reset, and a new initial state for the targets
        /// will be returned in subsequent changes.
        ///
        /// After the initial state is complete, `CURRENT` will be returned even
        /// if the target was previously indicated to be `CURRENT`.
        Reset,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [TargetChangeType::value] or
        /// [TargetChangeType::name].
        UnknownValue(target_change_type::UnknownValue),
    }

    #[doc(hidden)]
    pub mod target_change_type {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl TargetChangeType {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::NoChange => std::option::Option::Some(0),
                Self::Add => std::option::Option::Some(1),
                Self::Remove => std::option::Option::Some(2),
                Self::Current => std::option::Option::Some(3),
                Self::Reset => std::option::Option::Some(4),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::NoChange => std::option::Option::Some("NO_CHANGE"),
                Self::Add => std::option::Option::Some("ADD"),
                Self::Remove => std::option::Option::Some("REMOVE"),
                Self::Current => std::option::Option::Some("CURRENT"),
                Self::Reset => std::option::Option::Some("RESET"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for TargetChangeType {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for TargetChangeType {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for TargetChangeType {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::NoChange,
                1 => Self::Add,
                2 => Self::Remove,
                3 => Self::Current,
                4 => Self::Reset,
                _ => Self::UnknownValue(target_change_type::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for TargetChangeType {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "NO_CHANGE" => Self::NoChange,
                "ADD" => Self::Add,
                "REMOVE" => Self::Remove,
                "CURRENT" => Self::Current,
                "RESET" => Self::Reset,
                _ => Self::UnknownValue(target_change_type::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for TargetChangeType {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::NoChange => serializer.serialize_i32(0),
                Self::Add => serializer.serialize_i32(1),
                Self::Remove => serializer.serialize_i32(2),
                Self::Current => serializer.serialize_i32(3),
                Self::Reset => serializer.serialize_i32(4),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for TargetChangeType {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<TargetChangeType>::new(
                ".google.firestore.v1.TargetChange.TargetChangeType",
            ))
        }
    }
}

/// The request for
/// [Firestore.ListCollectionIds][google.firestore.v1.Firestore.ListCollectionIds].
///
/// [google.firestore.v1.Firestore.ListCollectionIds]: crate::client::Firestore::list_collection_ids
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ListCollectionIdsRequest {
    /// Required. The parent document. In the format:
    /// `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
    /// For example:
    /// `projects/my-project/databases/my-database/documents/chatrooms/my-chatroom`
    pub parent: std::string::String,

    /// The maximum number of results to return.
    pub page_size: i32,

    /// A page token. Must be a value from
    /// [ListCollectionIdsResponse][google.firestore.v1.ListCollectionIdsResponse].
    ///
    /// [google.firestore.v1.ListCollectionIdsResponse]: crate::model::ListCollectionIdsResponse
    pub page_token: std::string::String,

    /// The consistency mode for this request.
    /// If not set, defaults to strong consistency.
    pub consistency_selector:
        std::option::Option<crate::model::list_collection_ids_request::ConsistencySelector>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ListCollectionIdsRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [parent][crate::model::ListCollectionIdsRequest::parent].
    pub fn set_parent<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.parent = v.into();
        self
    }

    /// Sets the value of [page_size][crate::model::ListCollectionIdsRequest::page_size].
    pub fn set_page_size<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.page_size = v.into();
        self
    }

    /// Sets the value of [page_token][crate::model::ListCollectionIdsRequest::page_token].
    pub fn set_page_token<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.page_token = v.into();
        self
    }

    /// Sets the value of [consistency_selector][crate::model::ListCollectionIdsRequest::consistency_selector].
    ///
    /// Note that all the setters affecting `consistency_selector` are mutually
    /// exclusive.
    pub fn set_consistency_selector<
        T: std::convert::Into<
                std::option::Option<crate::model::list_collection_ids_request::ConsistencySelector>,
            >,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.consistency_selector = v.into();
        self
    }

    /// The value of [consistency_selector][crate::model::ListCollectionIdsRequest::consistency_selector]
    /// if it holds a `ReadTime`, `None` if the field is not set or
    /// holds a different branch.
    pub fn read_time(&self) -> std::option::Option<&std::boxed::Box<wkt::Timestamp>> {
        #[allow(unreachable_patterns)]
        self.consistency_selector.as_ref().and_then(|v| match v {
            crate::model::list_collection_ids_request::ConsistencySelector::ReadTime(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [consistency_selector][crate::model::ListCollectionIdsRequest::consistency_selector]
    /// to hold a `ReadTime`.
    ///
    /// Note that all the setters affecting `consistency_selector` are
    /// mutually exclusive.
    pub fn set_read_time<T: std::convert::Into<std::boxed::Box<wkt::Timestamp>>>(
        mut self,
        v: T,
    ) -> Self {
        self.consistency_selector = std::option::Option::Some(
            crate::model::list_collection_ids_request::ConsistencySelector::ReadTime(v.into()),
        );
        self
    }
}

impl wkt::message::Message for ListCollectionIdsRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.ListCollectionIdsRequest"
    }
}

/// Defines additional types related to [ListCollectionIdsRequest].
pub mod list_collection_ids_request {
    #[allow(unused_imports)]
    use super::*;

    /// The consistency mode for this request.
    /// If not set, defaults to strong consistency.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum ConsistencySelector {
        /// Reads documents as they were at the given time.
        ///
        /// This must be a microsecond precision timestamp within the past one hour,
        /// or if Point-in-Time Recovery is enabled, can additionally be a whole
        /// minute timestamp within the past 7 days.
        ReadTime(std::boxed::Box<wkt::Timestamp>),
    }

    impl ConsistencySelector {
        /// Initializes the enum to the [ReadTime](Self::ReadTime) branch.
        pub fn from_read_time(
            value: impl std::convert::Into<std::boxed::Box<wkt::Timestamp>>,
        ) -> Self {
            Self::ReadTime(value.into())
        }
    }
}

/// The response from
/// [Firestore.ListCollectionIds][google.firestore.v1.Firestore.ListCollectionIds].
///
/// [google.firestore.v1.Firestore.ListCollectionIds]: crate::client::Firestore::list_collection_ids
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ListCollectionIdsResponse {
    /// The collection ids.
    pub collection_ids: std::vec::Vec<std::string::String>,

    /// A page token that may be used to continue the list.
    pub next_page_token: std::string::String,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ListCollectionIdsResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [collection_ids][crate::model::ListCollectionIdsResponse::collection_ids].
    pub fn set_collection_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.collection_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [next_page_token][crate::model::ListCollectionIdsResponse::next_page_token].
    pub fn set_next_page_token<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.next_page_token = v.into();
        self
    }
}

impl wkt::message::Message for ListCollectionIdsResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.ListCollectionIdsResponse"
    }
}

/// The request for
/// [Firestore.BatchWrite][google.firestore.v1.Firestore.BatchWrite].
///
/// [google.firestore.v1.Firestore.BatchWrite]: crate::client::Firestore::batch_write
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct BatchWriteRequest {
    /// Required. The database name. In the format:
    /// `projects/{project_id}/databases/{database_id}`.
    pub database: std::string::String,

    /// The writes to apply.
    ///
    /// Method does not apply writes atomically and does not guarantee ordering.
    /// Each write succeeds or fails independently. You cannot write to the same
    /// document more than once per request.
    pub writes: std::vec::Vec<crate::model::Write>,

    /// Labels associated with this batch write.
    pub labels: std::collections::HashMap<std::string::String, std::string::String>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl BatchWriteRequest {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [database][crate::model::BatchWriteRequest::database].
    pub fn set_database<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.database = v.into();
        self
    }

    /// Sets the value of [writes][crate::model::BatchWriteRequest::writes].
    pub fn set_writes<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::Write>,
    {
        use std::iter::Iterator;
        self.writes = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [labels][crate::model::BatchWriteRequest::labels].
    pub fn set_labels<T, K, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = (K, V)>,
        K: std::convert::Into<std::string::String>,
        V: std::convert::Into<std::string::String>,
    {
        use std::iter::Iterator;
        self.labels = v.into_iter().map(|(k, v)| (k.into(), v.into())).collect();
        self
    }
}

impl wkt::message::Message for BatchWriteRequest {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.BatchWriteRequest"
    }
}

/// The response from
/// [Firestore.BatchWrite][google.firestore.v1.Firestore.BatchWrite].
///
/// [google.firestore.v1.Firestore.BatchWrite]: crate::client::Firestore::batch_write
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct BatchWriteResponse {
    /// The result of applying the writes.
    ///
    /// This i-th write result corresponds to the i-th write in the
    /// request.
    pub write_results: std::vec::Vec<crate::model::WriteResult>,

    /// The status of applying the writes.
    ///
    /// This i-th write status corresponds to the i-th write in the
    /// request.
    pub status: std::vec::Vec<rpc::model::Status>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl BatchWriteResponse {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [write_results][crate::model::BatchWriteResponse::write_results].
    pub fn set_write_results<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::WriteResult>,
    {
        use std::iter::Iterator;
        self.write_results = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [status][crate::model::BatchWriteResponse::status].
    pub fn set_status<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<rpc::model::Status>,
    {
        use std::iter::Iterator;
        self.status = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for BatchWriteResponse {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.BatchWriteResponse"
    }
}

/// A Firestore query.
///
/// The query stages are executed in the following order:
///
/// 1. from
/// 1. where
/// 1. select
/// 1. order_by + start_at + end_at
/// 1. offset
/// 1. limit
/// 1. find_nearest
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct StructuredQuery {
    /// Optional sub-set of the fields to return.
    ///
    /// This acts as a [DocumentMask][google.firestore.v1.DocumentMask] over the
    /// documents returned from a query. When not set, assumes that the caller
    /// wants all fields returned.
    ///
    /// [google.firestore.v1.DocumentMask]: crate::model::DocumentMask
    pub select: std::option::Option<crate::model::structured_query::Projection>,

    /// The collections to query.
    pub from: std::vec::Vec<crate::model::structured_query::CollectionSelector>,

    /// The filter to apply.
    pub r#where: std::option::Option<crate::model::structured_query::Filter>,

    /// The order to apply to the query results.
    ///
    /// Firestore allows callers to provide a full ordering, a partial ordering, or
    /// no ordering at all. In all cases, Firestore guarantees a stable ordering
    /// through the following rules:
    ///
    /// * The `order_by` is required to reference all fields used with an
    ///   inequality filter.
    /// * All fields that are required to be in the `order_by` but are not already
    ///   present are appended in lexicographical ordering of the field name.
    /// * If an order on `__name__` is not specified, it is appended by default.
    ///
    /// Fields are appended with the same sort direction as the last order
    /// specified, or 'ASCENDING' if no order was specified. For example:
    ///
    /// * `ORDER BY a` becomes `ORDER BY a ASC, __name__ ASC`
    /// * `ORDER BY a DESC` becomes `ORDER BY a DESC, __name__ DESC`
    /// * `WHERE a > 1` becomes `WHERE a > 1 ORDER BY a ASC, __name__ ASC`
    /// * `WHERE __name__ > ... AND a > 1` becomes
    ///   `WHERE __name__ > ... AND a > 1 ORDER BY a ASC, __name__ ASC`
    pub order_by: std::vec::Vec<crate::model::structured_query::Order>,

    /// A potential prefix of a position in the result set to start the query at.
    ///
    /// The ordering of the result set is based on the `ORDER BY` clause of the
    /// original query.
    ///
    /// ```norust
    /// SELECT * FROM k WHERE a = 1 AND b > 2 ORDER BY b ASC, __name__ ASC;
    /// ```
    ///
    /// This query's results are ordered by `(b ASC, __name__ ASC)`.
    ///
    /// Cursors can reference either the full ordering or a prefix of the location,
    /// though it cannot reference more fields than what are in the provided
    /// `ORDER BY`.
    ///
    /// Continuing off the example above, attaching the following start cursors
    /// will have varying impact:
    ///
    /// - `START BEFORE (2, /k/123)`: start the query right before `a = 1 AND
    ///   b > 2 AND __name__ > /k/123`.
    /// - `START AFTER (10)`: start the query right after `a = 1 AND b > 10`.
    ///
    /// Unlike `OFFSET` which requires scanning over the first N results to skip,
    /// a start cursor allows the query to begin at a logical position. This
    /// position is not required to match an actual result, it will scan forward
    /// from this position to find the next document.
    ///
    /// Requires:
    ///
    /// * The number of values cannot be greater than the number of fields
    ///   specified in the `ORDER BY` clause.
    pub start_at: std::option::Option<crate::model::Cursor>,

    /// A potential prefix of a position in the result set to end the query at.
    ///
    /// This is similar to `START_AT` but with it controlling the end position
    /// rather than the start position.
    ///
    /// Requires:
    ///
    /// * The number of values cannot be greater than the number of fields
    ///   specified in the `ORDER BY` clause.
    pub end_at: std::option::Option<crate::model::Cursor>,

    /// The number of documents to skip before returning the first result.
    ///
    /// This applies after the constraints specified by the `WHERE`, `START AT`, &
    /// `END AT` but before the `LIMIT` clause.
    ///
    /// Requires:
    ///
    /// * The value must be greater than or equal to zero if specified.
    pub offset: i32,

    /// The maximum number of results to return.
    ///
    /// Applies after all other constraints.
    ///
    /// Requires:
    ///
    /// * The value must be greater than or equal to zero if specified.
    pub limit: std::option::Option<wkt::Int32Value>,

    /// Optional. A potential nearest neighbors search.
    ///
    /// Applies after all other filters and ordering.
    ///
    /// Finds the closest vector embeddings to the given query vector.
    pub find_nearest: std::option::Option<crate::model::structured_query::FindNearest>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl StructuredQuery {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [select][crate::model::StructuredQuery::select].
    pub fn set_select<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::structured_query::Projection>,
    {
        self.select = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [select][crate::model::StructuredQuery::select].
    pub fn set_or_clear_select<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::structured_query::Projection>,
    {
        self.select = v.map(|x| x.into());
        self
    }

    /// Sets the value of [from][crate::model::StructuredQuery::from].
    pub fn set_from<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::structured_query::CollectionSelector>,
    {
        use std::iter::Iterator;
        self.from = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [r#where][crate::model::StructuredQuery::where].
    pub fn set_where<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::structured_query::Filter>,
    {
        self.r#where = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [r#where][crate::model::StructuredQuery::where].
    pub fn set_or_clear_where<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::structured_query::Filter>,
    {
        self.r#where = v.map(|x| x.into());
        self
    }

    /// Sets the value of [order_by][crate::model::StructuredQuery::order_by].
    pub fn set_order_by<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::structured_query::Order>,
    {
        use std::iter::Iterator;
        self.order_by = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [start_at][crate::model::StructuredQuery::start_at].
    pub fn set_start_at<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Cursor>,
    {
        self.start_at = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [start_at][crate::model::StructuredQuery::start_at].
    pub fn set_or_clear_start_at<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Cursor>,
    {
        self.start_at = v.map(|x| x.into());
        self
    }

    /// Sets the value of [end_at][crate::model::StructuredQuery::end_at].
    pub fn set_end_at<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Cursor>,
    {
        self.end_at = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [end_at][crate::model::StructuredQuery::end_at].
    pub fn set_or_clear_end_at<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Cursor>,
    {
        self.end_at = v.map(|x| x.into());
        self
    }

    /// Sets the value of [offset][crate::model::StructuredQuery::offset].
    pub fn set_offset<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.offset = v.into();
        self
    }

    /// Sets the value of [limit][crate::model::StructuredQuery::limit].
    pub fn set_limit<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Int32Value>,
    {
        self.limit = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [limit][crate::model::StructuredQuery::limit].
    pub fn set_or_clear_limit<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Int32Value>,
    {
        self.limit = v.map(|x| x.into());
        self
    }

    /// Sets the value of [find_nearest][crate::model::StructuredQuery::find_nearest].
    pub fn set_find_nearest<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::structured_query::FindNearest>,
    {
        self.find_nearest = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [find_nearest][crate::model::StructuredQuery::find_nearest].
    pub fn set_or_clear_find_nearest<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::structured_query::FindNearest>,
    {
        self.find_nearest = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for StructuredQuery {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.StructuredQuery"
    }
}

/// Defines additional types related to [StructuredQuery].
pub mod structured_query {
    #[allow(unused_imports)]
    use super::*;

    /// A selection of a collection, such as `messages as m1`.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct CollectionSelector {
        /// The collection ID.
        /// When set, selects only collections with this ID.
        pub collection_id: std::string::String,

        /// When false, selects only collections that are immediate children of
        /// the `parent` specified in the containing `RunQueryRequest`.
        /// When true, selects all descendant collections.
        pub all_descendants: bool,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl CollectionSelector {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [collection_id][crate::model::structured_query::CollectionSelector::collection_id].
        pub fn set_collection_id<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.collection_id = v.into();
            self
        }

        /// Sets the value of [all_descendants][crate::model::structured_query::CollectionSelector::all_descendants].
        pub fn set_all_descendants<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
            self.all_descendants = v.into();
            self
        }
    }

    impl wkt::message::Message for CollectionSelector {
        fn typename() -> &'static str {
            "type.googleapis.com/google.firestore.v1.StructuredQuery.CollectionSelector"
        }
    }

    /// A filter.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct Filter {
        /// The type of filter.
        pub filter_type: std::option::Option<crate::model::structured_query::filter::FilterType>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl Filter {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [filter_type][crate::model::structured_query::Filter::filter_type].
        ///
        /// Note that all the setters affecting `filter_type` are mutually
        /// exclusive.
        pub fn set_filter_type<
            T: std::convert::Into<
                    std::option::Option<crate::model::structured_query::filter::FilterType>,
                >,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.filter_type = v.into();
            self
        }

        /// The value of [filter_type][crate::model::structured_query::Filter::filter_type]
        /// if it holds a `CompositeFilter`, `None` if the field is not set or
        /// holds a different branch.
        pub fn composite_filter(
            &self,
        ) -> std::option::Option<&std::boxed::Box<crate::model::structured_query::CompositeFilter>>
        {
            #[allow(unreachable_patterns)]
            self.filter_type.as_ref().and_then(|v| match v {
                crate::model::structured_query::filter::FilterType::CompositeFilter(v) => {
                    std::option::Option::Some(v)
                }
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [filter_type][crate::model::structured_query::Filter::filter_type]
        /// to hold a `CompositeFilter`.
        ///
        /// Note that all the setters affecting `filter_type` are
        /// mutually exclusive.
        pub fn set_composite_filter<
            T: std::convert::Into<std::boxed::Box<crate::model::structured_query::CompositeFilter>>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.filter_type = std::option::Option::Some(
                crate::model::structured_query::filter::FilterType::CompositeFilter(v.into()),
            );
            self
        }

        /// The value of [filter_type][crate::model::structured_query::Filter::filter_type]
        /// if it holds a `FieldFilter`, `None` if the field is not set or
        /// holds a different branch.
        pub fn field_filter(
            &self,
        ) -> std::option::Option<&std::boxed::Box<crate::model::structured_query::FieldFilter>>
        {
            #[allow(unreachable_patterns)]
            self.filter_type.as_ref().and_then(|v| match v {
                crate::model::structured_query::filter::FilterType::FieldFilter(v) => {
                    std::option::Option::Some(v)
                }
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [filter_type][crate::model::structured_query::Filter::filter_type]
        /// to hold a `FieldFilter`.
        ///
        /// Note that all the setters affecting `filter_type` are
        /// mutually exclusive.
        pub fn set_field_filter<
            T: std::convert::Into<std::boxed::Box<crate::model::structured_query::FieldFilter>>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.filter_type = std::option::Option::Some(
                crate::model::structured_query::filter::FilterType::FieldFilter(v.into()),
            );
            self
        }

        /// The value of [filter_type][crate::model::structured_query::Filter::filter_type]
        /// if it holds a `UnaryFilter`, `None` if the field is not set or
        /// holds a different branch.
        pub fn unary_filter(
            &self,
        ) -> std::option::Option<&std::boxed::Box<crate::model::structured_query::UnaryFilter>>
        {
            #[allow(unreachable_patterns)]
            self.filter_type.as_ref().and_then(|v| match v {
                crate::model::structured_query::filter::FilterType::UnaryFilter(v) => {
                    std::option::Option::Some(v)
                }
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [filter_type][crate::model::structured_query::Filter::filter_type]
        /// to hold a `UnaryFilter`.
        ///
        /// Note that all the setters affecting `filter_type` are
        /// mutually exclusive.
        pub fn set_unary_filter<
            T: std::convert::Into<std::boxed::Box<crate::model::structured_query::UnaryFilter>>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.filter_type = std::option::Option::Some(
                crate::model::structured_query::filter::FilterType::UnaryFilter(v.into()),
            );
            self
        }
    }

    impl wkt::message::Message for Filter {
        fn typename() -> &'static str {
            "type.googleapis.com/google.firestore.v1.StructuredQuery.Filter"
        }
    }

    /// Defines additional types related to [Filter].
    pub mod filter {
        #[allow(unused_imports)]
        use super::*;

        /// The type of filter.
        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum FilterType {
            /// A composite filter.
            CompositeFilter(std::boxed::Box<crate::model::structured_query::CompositeFilter>),
            /// A filter on a document field.
            FieldFilter(std::boxed::Box<crate::model::structured_query::FieldFilter>),
            /// A filter that takes exactly one argument.
            UnaryFilter(std::boxed::Box<crate::model::structured_query::UnaryFilter>),
        }

        impl FilterType {
            /// Initializes the enum to the [CompositeFilter](Self::CompositeFilter) branch.
            pub fn from_composite_filter(
                value: impl std::convert::Into<
                    std::boxed::Box<crate::model::structured_query::CompositeFilter>,
                >,
            ) -> Self {
                Self::CompositeFilter(value.into())
            }
            /// Initializes the enum to the [FieldFilter](Self::FieldFilter) branch.
            pub fn from_field_filter(
                value: impl std::convert::Into<
                    std::boxed::Box<crate::model::structured_query::FieldFilter>,
                >,
            ) -> Self {
                Self::FieldFilter(value.into())
            }
            /// Initializes the enum to the [UnaryFilter](Self::UnaryFilter) branch.
            pub fn from_unary_filter(
                value: impl std::convert::Into<
                    std::boxed::Box<crate::model::structured_query::UnaryFilter>,
                >,
            ) -> Self {
                Self::UnaryFilter(value.into())
            }
        }
    }

    /// A filter that merges multiple other filters using the given operator.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct CompositeFilter {
        /// The operator for combining multiple filters.
        pub op: crate::model::structured_query::composite_filter::Operator,

        /// The list of filters to combine.
        ///
        /// Requires:
        ///
        /// * At least one filter is present.
        pub filters: std::vec::Vec<crate::model::structured_query::Filter>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl CompositeFilter {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [op][crate::model::structured_query::CompositeFilter::op].
        pub fn set_op<
            T: std::convert::Into<crate::model::structured_query::composite_filter::Operator>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.op = v.into();
            self
        }

        /// Sets the value of [filters][crate::model::structured_query::CompositeFilter::filters].
        pub fn set_filters<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<crate::model::structured_query::Filter>,
        {
            use std::iter::Iterator;
            self.filters = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for CompositeFilter {
        fn typename() -> &'static str {
            "type.googleapis.com/google.firestore.v1.StructuredQuery.CompositeFilter"
        }
    }

    /// Defines additional types related to [CompositeFilter].
    pub mod composite_filter {
        #[allow(unused_imports)]
        use super::*;

        /// A composite filter operator.
        ///
        /// # Working with unknown values
        ///
        /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
        /// additional enum variants at any time. Adding new variants is not considered
        /// a breaking change. Applications should write their code in anticipation of:
        ///
        /// - New values appearing in future releases of the client library, **and**
        /// - New values received dynamically, without application changes.
        ///
        /// Please consult the [Working with enums] section in the user guide for some
        /// guidelines.
        ///
        /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum Operator {
            /// Unspecified. This value must not be used.
            Unspecified,
            /// Documents are required to satisfy all of the combined filters.
            And,
            /// Documents are required to satisfy at least one of the combined filters.
            Or,
            /// If set, the enum was initialized with an unknown value.
            ///
            /// Applications can examine the value using [Operator::value] or
            /// [Operator::name].
            UnknownValue(operator::UnknownValue),
        }

        #[doc(hidden)]
        pub mod operator {
            #[allow(unused_imports)]
            use super::*;
            #[derive(Clone, Debug, PartialEq)]
            pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
        }

        impl Operator {
            /// Gets the enum value.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the string representation of enums.
            pub fn value(&self) -> std::option::Option<i32> {
                match self {
                    Self::Unspecified => std::option::Option::Some(0),
                    Self::And => std::option::Option::Some(1),
                    Self::Or => std::option::Option::Some(2),
                    Self::UnknownValue(u) => u.0.value(),
                }
            }

            /// Gets the enum value as a string.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the integer representation of enums.
            pub fn name(&self) -> std::option::Option<&str> {
                match self {
                    Self::Unspecified => std::option::Option::Some("OPERATOR_UNSPECIFIED"),
                    Self::And => std::option::Option::Some("AND"),
                    Self::Or => std::option::Option::Some("OR"),
                    Self::UnknownValue(u) => u.0.name(),
                }
            }
        }

        impl std::default::Default for Operator {
            fn default() -> Self {
                use std::convert::From;
                Self::from(0)
            }
        }

        impl std::fmt::Display for Operator {
            fn fmt(
                &self,
                f: &mut std::fmt::Formatter<'_>,
            ) -> std::result::Result<(), std::fmt::Error> {
                wkt::internal::display_enum(f, self.name(), self.value())
            }
        }

        impl std::convert::From<i32> for Operator {
            fn from(value: i32) -> Self {
                match value {
                    0 => Self::Unspecified,
                    1 => Self::And,
                    2 => Self::Or,
                    _ => Self::UnknownValue(operator::UnknownValue(
                        wkt::internal::UnknownEnumValue::Integer(value),
                    )),
                }
            }
        }

        impl std::convert::From<&str> for Operator {
            fn from(value: &str) -> Self {
                use std::string::ToString;
                match value {
                    "OPERATOR_UNSPECIFIED" => Self::Unspecified,
                    "AND" => Self::And,
                    "OR" => Self::Or,
                    _ => Self::UnknownValue(operator::UnknownValue(
                        wkt::internal::UnknownEnumValue::String(value.to_string()),
                    )),
                }
            }
        }

        impl serde::ser::Serialize for Operator {
            fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
            where
                S: serde::Serializer,
            {
                match self {
                    Self::Unspecified => serializer.serialize_i32(0),
                    Self::And => serializer.serialize_i32(1),
                    Self::Or => serializer.serialize_i32(2),
                    Self::UnknownValue(u) => u.0.serialize(serializer),
                }
            }
        }

        impl<'de> serde::de::Deserialize<'de> for Operator {
            fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
            where
                D: serde::Deserializer<'de>,
            {
                deserializer.deserialize_any(wkt::internal::EnumVisitor::<Operator>::new(
                    ".google.firestore.v1.StructuredQuery.CompositeFilter.Operator",
                ))
            }
        }
    }

    /// A filter on a specific field.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct FieldFilter {
        /// The field to filter by.
        pub field: std::option::Option<crate::model::structured_query::FieldReference>,

        /// The operator to filter by.
        pub op: crate::model::structured_query::field_filter::Operator,

        /// The value to compare to.
        pub value: std::option::Option<crate::model::Value>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl FieldFilter {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [field][crate::model::structured_query::FieldFilter::field].
        pub fn set_field<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::structured_query::FieldReference>,
        {
            self.field = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [field][crate::model::structured_query::FieldFilter::field].
        pub fn set_or_clear_field<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::structured_query::FieldReference>,
        {
            self.field = v.map(|x| x.into());
            self
        }

        /// Sets the value of [op][crate::model::structured_query::FieldFilter::op].
        pub fn set_op<
            T: std::convert::Into<crate::model::structured_query::field_filter::Operator>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.op = v.into();
            self
        }

        /// Sets the value of [value][crate::model::structured_query::FieldFilter::value].
        pub fn set_value<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::Value>,
        {
            self.value = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [value][crate::model::structured_query::FieldFilter::value].
        pub fn set_or_clear_value<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::Value>,
        {
            self.value = v.map(|x| x.into());
            self
        }
    }

    impl wkt::message::Message for FieldFilter {
        fn typename() -> &'static str {
            "type.googleapis.com/google.firestore.v1.StructuredQuery.FieldFilter"
        }
    }

    /// Defines additional types related to [FieldFilter].
    pub mod field_filter {
        #[allow(unused_imports)]
        use super::*;

        /// A field filter operator.
        ///
        /// # Working with unknown values
        ///
        /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
        /// additional enum variants at any time. Adding new variants is not considered
        /// a breaking change. Applications should write their code in anticipation of:
        ///
        /// - New values appearing in future releases of the client library, **and**
        /// - New values received dynamically, without application changes.
        ///
        /// Please consult the [Working with enums] section in the user guide for some
        /// guidelines.
        ///
        /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum Operator {
            /// Unspecified. This value must not be used.
            Unspecified,
            /// The given `field` is less than the given `value`.
            ///
            /// Requires:
            ///
            /// * That `field` come first in `order_by`.
            LessThan,
            /// The given `field` is less than or equal to the given `value`.
            ///
            /// Requires:
            ///
            /// * That `field` come first in `order_by`.
            LessThanOrEqual,
            /// The given `field` is greater than the given `value`.
            ///
            /// Requires:
            ///
            /// * That `field` come first in `order_by`.
            GreaterThan,
            /// The given `field` is greater than or equal to the given `value`.
            ///
            /// Requires:
            ///
            /// * That `field` come first in `order_by`.
            GreaterThanOrEqual,
            /// The given `field` is equal to the given `value`.
            Equal,
            /// The given `field` is not equal to the given `value`.
            ///
            /// Requires:
            ///
            /// * No other `NOT_EQUAL`, `NOT_IN`, `IS_NOT_NULL`, or `IS_NOT_NAN`.
            /// * That `field` comes first in the `order_by`.
            NotEqual,
            /// The given `field` is an array that contains the given `value`.
            ArrayContains,
            /// The given `field` is equal to at least one value in the given array.
            ///
            /// Requires:
            ///
            /// * That `value` is a non-empty `ArrayValue`, subject to disjunction
            ///   limits.
            /// * No `NOT_IN` filters in the same query.
            In,
            /// The given `field` is an array that contains any of the values in the
            /// given array.
            ///
            /// Requires:
            ///
            /// * That `value` is a non-empty `ArrayValue`, subject to disjunction
            ///   limits.
            /// * No other `ARRAY_CONTAINS_ANY` filters within the same disjunction.
            /// * No `NOT_IN` filters in the same query.
            ArrayContainsAny,
            /// The value of the `field` is not in the given array.
            ///
            /// Requires:
            ///
            /// * That `value` is a non-empty `ArrayValue` with at most 10 values.
            /// * No other `OR`, `IN`, `ARRAY_CONTAINS_ANY`, `NOT_IN`, `NOT_EQUAL`,
            ///   `IS_NOT_NULL`, or `IS_NOT_NAN`.
            /// * That `field` comes first in the `order_by`.
            NotIn,
            /// If set, the enum was initialized with an unknown value.
            ///
            /// Applications can examine the value using [Operator::value] or
            /// [Operator::name].
            UnknownValue(operator::UnknownValue),
        }

        #[doc(hidden)]
        pub mod operator {
            #[allow(unused_imports)]
            use super::*;
            #[derive(Clone, Debug, PartialEq)]
            pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
        }

        impl Operator {
            /// Gets the enum value.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the string representation of enums.
            pub fn value(&self) -> std::option::Option<i32> {
                match self {
                    Self::Unspecified => std::option::Option::Some(0),
                    Self::LessThan => std::option::Option::Some(1),
                    Self::LessThanOrEqual => std::option::Option::Some(2),
                    Self::GreaterThan => std::option::Option::Some(3),
                    Self::GreaterThanOrEqual => std::option::Option::Some(4),
                    Self::Equal => std::option::Option::Some(5),
                    Self::NotEqual => std::option::Option::Some(6),
                    Self::ArrayContains => std::option::Option::Some(7),
                    Self::In => std::option::Option::Some(8),
                    Self::ArrayContainsAny => std::option::Option::Some(9),
                    Self::NotIn => std::option::Option::Some(10),
                    Self::UnknownValue(u) => u.0.value(),
                }
            }

            /// Gets the enum value as a string.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the integer representation of enums.
            pub fn name(&self) -> std::option::Option<&str> {
                match self {
                    Self::Unspecified => std::option::Option::Some("OPERATOR_UNSPECIFIED"),
                    Self::LessThan => std::option::Option::Some("LESS_THAN"),
                    Self::LessThanOrEqual => std::option::Option::Some("LESS_THAN_OR_EQUAL"),
                    Self::GreaterThan => std::option::Option::Some("GREATER_THAN"),
                    Self::GreaterThanOrEqual => std::option::Option::Some("GREATER_THAN_OR_EQUAL"),
                    Self::Equal => std::option::Option::Some("EQUAL"),
                    Self::NotEqual => std::option::Option::Some("NOT_EQUAL"),
                    Self::ArrayContains => std::option::Option::Some("ARRAY_CONTAINS"),
                    Self::In => std::option::Option::Some("IN"),
                    Self::ArrayContainsAny => std::option::Option::Some("ARRAY_CONTAINS_ANY"),
                    Self::NotIn => std::option::Option::Some("NOT_IN"),
                    Self::UnknownValue(u) => u.0.name(),
                }
            }
        }

        impl std::default::Default for Operator {
            fn default() -> Self {
                use std::convert::From;
                Self::from(0)
            }
        }

        impl std::fmt::Display for Operator {
            fn fmt(
                &self,
                f: &mut std::fmt::Formatter<'_>,
            ) -> std::result::Result<(), std::fmt::Error> {
                wkt::internal::display_enum(f, self.name(), self.value())
            }
        }

        impl std::convert::From<i32> for Operator {
            fn from(value: i32) -> Self {
                match value {
                    0 => Self::Unspecified,
                    1 => Self::LessThan,
                    2 => Self::LessThanOrEqual,
                    3 => Self::GreaterThan,
                    4 => Self::GreaterThanOrEqual,
                    5 => Self::Equal,
                    6 => Self::NotEqual,
                    7 => Self::ArrayContains,
                    8 => Self::In,
                    9 => Self::ArrayContainsAny,
                    10 => Self::NotIn,
                    _ => Self::UnknownValue(operator::UnknownValue(
                        wkt::internal::UnknownEnumValue::Integer(value),
                    )),
                }
            }
        }

        impl std::convert::From<&str> for Operator {
            fn from(value: &str) -> Self {
                use std::string::ToString;
                match value {
                    "OPERATOR_UNSPECIFIED" => Self::Unspecified,
                    "LESS_THAN" => Self::LessThan,
                    "LESS_THAN_OR_EQUAL" => Self::LessThanOrEqual,
                    "GREATER_THAN" => Self::GreaterThan,
                    "GREATER_THAN_OR_EQUAL" => Self::GreaterThanOrEqual,
                    "EQUAL" => Self::Equal,
                    "NOT_EQUAL" => Self::NotEqual,
                    "ARRAY_CONTAINS" => Self::ArrayContains,
                    "IN" => Self::In,
                    "ARRAY_CONTAINS_ANY" => Self::ArrayContainsAny,
                    "NOT_IN" => Self::NotIn,
                    _ => Self::UnknownValue(operator::UnknownValue(
                        wkt::internal::UnknownEnumValue::String(value.to_string()),
                    )),
                }
            }
        }

        impl serde::ser::Serialize for Operator {
            fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
            where
                S: serde::Serializer,
            {
                match self {
                    Self::Unspecified => serializer.serialize_i32(0),
                    Self::LessThan => serializer.serialize_i32(1),
                    Self::LessThanOrEqual => serializer.serialize_i32(2),
                    Self::GreaterThan => serializer.serialize_i32(3),
                    Self::GreaterThanOrEqual => serializer.serialize_i32(4),
                    Self::Equal => serializer.serialize_i32(5),
                    Self::NotEqual => serializer.serialize_i32(6),
                    Self::ArrayContains => serializer.serialize_i32(7),
                    Self::In => serializer.serialize_i32(8),
                    Self::ArrayContainsAny => serializer.serialize_i32(9),
                    Self::NotIn => serializer.serialize_i32(10),
                    Self::UnknownValue(u) => u.0.serialize(serializer),
                }
            }
        }

        impl<'de> serde::de::Deserialize<'de> for Operator {
            fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
            where
                D: serde::Deserializer<'de>,
            {
                deserializer.deserialize_any(wkt::internal::EnumVisitor::<Operator>::new(
                    ".google.firestore.v1.StructuredQuery.FieldFilter.Operator",
                ))
            }
        }
    }

    /// A filter with a single operand.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct UnaryFilter {
        /// The unary operator to apply.
        pub op: crate::model::structured_query::unary_filter::Operator,

        /// The argument to the filter.
        pub operand_type:
            std::option::Option<crate::model::structured_query::unary_filter::OperandType>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl UnaryFilter {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [op][crate::model::structured_query::UnaryFilter::op].
        pub fn set_op<
            T: std::convert::Into<crate::model::structured_query::unary_filter::Operator>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.op = v.into();
            self
        }

        /// Sets the value of [operand_type][crate::model::structured_query::UnaryFilter::operand_type].
        ///
        /// Note that all the setters affecting `operand_type` are mutually
        /// exclusive.
        pub fn set_operand_type<
            T: std::convert::Into<
                    std::option::Option<crate::model::structured_query::unary_filter::OperandType>,
                >,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.operand_type = v.into();
            self
        }

        /// The value of [operand_type][crate::model::structured_query::UnaryFilter::operand_type]
        /// if it holds a `Field`, `None` if the field is not set or
        /// holds a different branch.
        pub fn field(
            &self,
        ) -> std::option::Option<&std::boxed::Box<crate::model::structured_query::FieldReference>>
        {
            #[allow(unreachable_patterns)]
            self.operand_type.as_ref().and_then(|v| match v {
                crate::model::structured_query::unary_filter::OperandType::Field(v) => {
                    std::option::Option::Some(v)
                }
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [operand_type][crate::model::structured_query::UnaryFilter::operand_type]
        /// to hold a `Field`.
        ///
        /// Note that all the setters affecting `operand_type` are
        /// mutually exclusive.
        pub fn set_field<
            T: std::convert::Into<std::boxed::Box<crate::model::structured_query::FieldReference>>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.operand_type = std::option::Option::Some(
                crate::model::structured_query::unary_filter::OperandType::Field(v.into()),
            );
            self
        }
    }

    impl wkt::message::Message for UnaryFilter {
        fn typename() -> &'static str {
            "type.googleapis.com/google.firestore.v1.StructuredQuery.UnaryFilter"
        }
    }

    /// Defines additional types related to [UnaryFilter].
    pub mod unary_filter {
        #[allow(unused_imports)]
        use super::*;

        /// A unary operator.
        ///
        /// # Working with unknown values
        ///
        /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
        /// additional enum variants at any time. Adding new variants is not considered
        /// a breaking change. Applications should write their code in anticipation of:
        ///
        /// - New values appearing in future releases of the client library, **and**
        /// - New values received dynamically, without application changes.
        ///
        /// Please consult the [Working with enums] section in the user guide for some
        /// guidelines.
        ///
        /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum Operator {
            /// Unspecified. This value must not be used.
            Unspecified,
            /// The given `field` is equal to `NaN`.
            IsNan,
            /// The given `field` is equal to `NULL`.
            IsNull,
            /// The given `field` is not equal to `NaN`.
            ///
            /// Requires:
            ///
            /// * No other `NOT_EQUAL`, `NOT_IN`, `IS_NOT_NULL`, or `IS_NOT_NAN`.
            /// * That `field` comes first in the `order_by`.
            IsNotNan,
            /// The given `field` is not equal to `NULL`.
            ///
            /// Requires:
            ///
            /// * A single `NOT_EQUAL`, `NOT_IN`, `IS_NOT_NULL`, or `IS_NOT_NAN`.
            /// * That `field` comes first in the `order_by`.
            IsNotNull,
            /// If set, the enum was initialized with an unknown value.
            ///
            /// Applications can examine the value using [Operator::value] or
            /// [Operator::name].
            UnknownValue(operator::UnknownValue),
        }

        #[doc(hidden)]
        pub mod operator {
            #[allow(unused_imports)]
            use super::*;
            #[derive(Clone, Debug, PartialEq)]
            pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
        }

        impl Operator {
            /// Gets the enum value.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the string representation of enums.
            pub fn value(&self) -> std::option::Option<i32> {
                match self {
                    Self::Unspecified => std::option::Option::Some(0),
                    Self::IsNan => std::option::Option::Some(2),
                    Self::IsNull => std::option::Option::Some(3),
                    Self::IsNotNan => std::option::Option::Some(4),
                    Self::IsNotNull => std::option::Option::Some(5),
                    Self::UnknownValue(u) => u.0.value(),
                }
            }

            /// Gets the enum value as a string.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the integer representation of enums.
            pub fn name(&self) -> std::option::Option<&str> {
                match self {
                    Self::Unspecified => std::option::Option::Some("OPERATOR_UNSPECIFIED"),
                    Self::IsNan => std::option::Option::Some("IS_NAN"),
                    Self::IsNull => std::option::Option::Some("IS_NULL"),
                    Self::IsNotNan => std::option::Option::Some("IS_NOT_NAN"),
                    Self::IsNotNull => std::option::Option::Some("IS_NOT_NULL"),
                    Self::UnknownValue(u) => u.0.name(),
                }
            }
        }

        impl std::default::Default for Operator {
            fn default() -> Self {
                use std::convert::From;
                Self::from(0)
            }
        }

        impl std::fmt::Display for Operator {
            fn fmt(
                &self,
                f: &mut std::fmt::Formatter<'_>,
            ) -> std::result::Result<(), std::fmt::Error> {
                wkt::internal::display_enum(f, self.name(), self.value())
            }
        }

        impl std::convert::From<i32> for Operator {
            fn from(value: i32) -> Self {
                match value {
                    0 => Self::Unspecified,
                    2 => Self::IsNan,
                    3 => Self::IsNull,
                    4 => Self::IsNotNan,
                    5 => Self::IsNotNull,
                    _ => Self::UnknownValue(operator::UnknownValue(
                        wkt::internal::UnknownEnumValue::Integer(value),
                    )),
                }
            }
        }

        impl std::convert::From<&str> for Operator {
            fn from(value: &str) -> Self {
                use std::string::ToString;
                match value {
                    "OPERATOR_UNSPECIFIED" => Self::Unspecified,
                    "IS_NAN" => Self::IsNan,
                    "IS_NULL" => Self::IsNull,
                    "IS_NOT_NAN" => Self::IsNotNan,
                    "IS_NOT_NULL" => Self::IsNotNull,
                    _ => Self::UnknownValue(operator::UnknownValue(
                        wkt::internal::UnknownEnumValue::String(value.to_string()),
                    )),
                }
            }
        }

        impl serde::ser::Serialize for Operator {
            fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
            where
                S: serde::Serializer,
            {
                match self {
                    Self::Unspecified => serializer.serialize_i32(0),
                    Self::IsNan => serializer.serialize_i32(2),
                    Self::IsNull => serializer.serialize_i32(3),
                    Self::IsNotNan => serializer.serialize_i32(4),
                    Self::IsNotNull => serializer.serialize_i32(5),
                    Self::UnknownValue(u) => u.0.serialize(serializer),
                }
            }
        }

        impl<'de> serde::de::Deserialize<'de> for Operator {
            fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
            where
                D: serde::Deserializer<'de>,
            {
                deserializer.deserialize_any(wkt::internal::EnumVisitor::<Operator>::new(
                    ".google.firestore.v1.StructuredQuery.UnaryFilter.Operator",
                ))
            }
        }

        /// The argument to the filter.
        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum OperandType {
            /// The field to which to apply the operator.
            Field(std::boxed::Box<crate::model::structured_query::FieldReference>),
        }

        impl OperandType {
            /// Initializes the enum to the [Field](Self::Field) branch.
            pub fn from_field(
                value: impl std::convert::Into<
                    std::boxed::Box<crate::model::structured_query::FieldReference>,
                >,
            ) -> Self {
                Self::Field(value.into())
            }
        }
    }

    /// An order on a field.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct Order {
        /// The field to order by.
        pub field: std::option::Option<crate::model::structured_query::FieldReference>,

        /// The direction to order by. Defaults to `ASCENDING`.
        pub direction: crate::model::structured_query::Direction,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl Order {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [field][crate::model::structured_query::Order::field].
        pub fn set_field<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::structured_query::FieldReference>,
        {
            self.field = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [field][crate::model::structured_query::Order::field].
        pub fn set_or_clear_field<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::structured_query::FieldReference>,
        {
            self.field = v.map(|x| x.into());
            self
        }

        /// Sets the value of [direction][crate::model::structured_query::Order::direction].
        pub fn set_direction<T: std::convert::Into<crate::model::structured_query::Direction>>(
            mut self,
            v: T,
        ) -> Self {
            self.direction = v.into();
            self
        }
    }

    impl wkt::message::Message for Order {
        fn typename() -> &'static str {
            "type.googleapis.com/google.firestore.v1.StructuredQuery.Order"
        }
    }

    /// A reference to a field in a document, ex: `stats.operations`.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct FieldReference {
        /// A reference to a field in a document.
        ///
        /// Requires:
        ///
        /// * MUST be a dot-delimited (`.`) string of segments, where each segment
        ///   conforms to [document field name][google.firestore.v1.Document.fields]
        ///   limitations.
        ///
        /// [google.firestore.v1.Document.fields]: crate::model::Document::fields
        pub field_path: std::string::String,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl FieldReference {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [field_path][crate::model::structured_query::FieldReference::field_path].
        pub fn set_field_path<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.field_path = v.into();
            self
        }
    }

    impl wkt::message::Message for FieldReference {
        fn typename() -> &'static str {
            "type.googleapis.com/google.firestore.v1.StructuredQuery.FieldReference"
        }
    }

    /// The projection of document's fields to return.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct Projection {
        /// The fields to return.
        ///
        /// If empty, all fields are returned. To only return the name
        /// of the document, use `['__name__']`.
        pub fields: std::vec::Vec<crate::model::structured_query::FieldReference>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl Projection {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [fields][crate::model::structured_query::Projection::fields].
        pub fn set_fields<T, V>(mut self, v: T) -> Self
        where
            T: std::iter::IntoIterator<Item = V>,
            V: std::convert::Into<crate::model::structured_query::FieldReference>,
        {
            use std::iter::Iterator;
            self.fields = v.into_iter().map(|i| i.into()).collect();
            self
        }
    }

    impl wkt::message::Message for Projection {
        fn typename() -> &'static str {
            "type.googleapis.com/google.firestore.v1.StructuredQuery.Projection"
        }
    }

    /// Nearest Neighbors search config. The ordering provided by FindNearest
    /// supersedes the order_by stage. If multiple documents have the same vector
    /// distance, the returned document order is not guaranteed to be stable
    /// between queries.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct FindNearest {
        /// Required. An indexed vector field to search upon. Only documents which
        /// contain vectors whose dimensionality match the query_vector can be
        /// returned.
        pub vector_field: std::option::Option<crate::model::structured_query::FieldReference>,

        /// Required. The query vector that we are searching on. Must be a vector of
        /// no more than 2048 dimensions.
        pub query_vector: std::option::Option<crate::model::Value>,

        /// Required. The distance measure to use, required.
        pub distance_measure: crate::model::structured_query::find_nearest::DistanceMeasure,

        /// Required. The number of nearest neighbors to return. Must be a positive
        /// integer of no more than 1000.
        pub limit: std::option::Option<wkt::Int32Value>,

        /// Optional. Optional name of the field to output the result of the vector
        /// distance calculation. Must conform to [document field
        /// name][google.firestore.v1.Document.fields] limitations.
        ///
        /// [google.firestore.v1.Document.fields]: crate::model::Document::fields
        pub distance_result_field: std::string::String,

        /// Optional. Option to specify a threshold for which no less similar
        /// documents will be returned. The behavior of the specified
        /// `distance_measure` will affect the meaning of the distance threshold.
        /// Since DOT_PRODUCT distances increase when the vectors are more similar,
        /// the comparison is inverted.
        ///
        /// * For EUCLIDEAN, COSINE: `WHERE distance <= distance_threshold`
        /// * For DOT_PRODUCT:       `WHERE distance >= distance_threshold`
        pub distance_threshold: std::option::Option<wkt::DoubleValue>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl FindNearest {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [vector_field][crate::model::structured_query::FindNearest::vector_field].
        pub fn set_vector_field<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::structured_query::FieldReference>,
        {
            self.vector_field = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [vector_field][crate::model::structured_query::FindNearest::vector_field].
        pub fn set_or_clear_vector_field<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::structured_query::FieldReference>,
        {
            self.vector_field = v.map(|x| x.into());
            self
        }

        /// Sets the value of [query_vector][crate::model::structured_query::FindNearest::query_vector].
        pub fn set_query_vector<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<crate::model::Value>,
        {
            self.query_vector = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [query_vector][crate::model::structured_query::FindNearest::query_vector].
        pub fn set_or_clear_query_vector<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<crate::model::Value>,
        {
            self.query_vector = v.map(|x| x.into());
            self
        }

        /// Sets the value of [distance_measure][crate::model::structured_query::FindNearest::distance_measure].
        pub fn set_distance_measure<
            T: std::convert::Into<crate::model::structured_query::find_nearest::DistanceMeasure>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.distance_measure = v.into();
            self
        }

        /// Sets the value of [limit][crate::model::structured_query::FindNearest::limit].
        pub fn set_limit<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::Int32Value>,
        {
            self.limit = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [limit][crate::model::structured_query::FindNearest::limit].
        pub fn set_or_clear_limit<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::Int32Value>,
        {
            self.limit = v.map(|x| x.into());
            self
        }

        /// Sets the value of [distance_result_field][crate::model::structured_query::FindNearest::distance_result_field].
        pub fn set_distance_result_field<T: std::convert::Into<std::string::String>>(
            mut self,
            v: T,
        ) -> Self {
            self.distance_result_field = v.into();
            self
        }

        /// Sets the value of [distance_threshold][crate::model::structured_query::FindNearest::distance_threshold].
        pub fn set_distance_threshold<T>(mut self, v: T) -> Self
        where
            T: std::convert::Into<wkt::DoubleValue>,
        {
            self.distance_threshold = std::option::Option::Some(v.into());
            self
        }

        /// Sets or clears the value of [distance_threshold][crate::model::structured_query::FindNearest::distance_threshold].
        pub fn set_or_clear_distance_threshold<T>(mut self, v: std::option::Option<T>) -> Self
        where
            T: std::convert::Into<wkt::DoubleValue>,
        {
            self.distance_threshold = v.map(|x| x.into());
            self
        }
    }

    impl wkt::message::Message for FindNearest {
        fn typename() -> &'static str {
            "type.googleapis.com/google.firestore.v1.StructuredQuery.FindNearest"
        }
    }

    /// Defines additional types related to [FindNearest].
    pub mod find_nearest {
        #[allow(unused_imports)]
        use super::*;

        /// The distance measure to use when comparing vectors.
        ///
        /// # Working with unknown values
        ///
        /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
        /// additional enum variants at any time. Adding new variants is not considered
        /// a breaking change. Applications should write their code in anticipation of:
        ///
        /// - New values appearing in future releases of the client library, **and**
        /// - New values received dynamically, without application changes.
        ///
        /// Please consult the [Working with enums] section in the user guide for some
        /// guidelines.
        ///
        /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum DistanceMeasure {
            /// Should not be set.
            Unspecified,
            /// Measures the EUCLIDEAN distance between the vectors. See
            /// [Euclidean](https://en.wikipedia.org/wiki/Euclidean_distance) to learn
            /// more. The resulting distance decreases the more similar two vectors
            /// are.
            Euclidean,
            /// COSINE distance compares vectors based on the angle between them, which
            /// allows you to measure similarity that isn't based on the vectors
            /// magnitude. We recommend using DOT_PRODUCT with unit normalized vectors
            /// instead of COSINE distance, which is mathematically equivalent with
            /// better performance. See [Cosine
            /// Similarity](https://en.wikipedia.org/wiki/Cosine_similarity) to learn
            /// more about COSINE similarity and COSINE distance. The resulting
            /// COSINE distance decreases the more similar two vectors are.
            Cosine,
            /// Similar to cosine but is affected by the magnitude of the vectors. See
            /// [Dot Product](https://en.wikipedia.org/wiki/Dot_product) to learn more.
            /// The resulting distance increases the more similar two vectors are.
            DotProduct,
            /// If set, the enum was initialized with an unknown value.
            ///
            /// Applications can examine the value using [DistanceMeasure::value] or
            /// [DistanceMeasure::name].
            UnknownValue(distance_measure::UnknownValue),
        }

        #[doc(hidden)]
        pub mod distance_measure {
            #[allow(unused_imports)]
            use super::*;
            #[derive(Clone, Debug, PartialEq)]
            pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
        }

        impl DistanceMeasure {
            /// Gets the enum value.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the string representation of enums.
            pub fn value(&self) -> std::option::Option<i32> {
                match self {
                    Self::Unspecified => std::option::Option::Some(0),
                    Self::Euclidean => std::option::Option::Some(1),
                    Self::Cosine => std::option::Option::Some(2),
                    Self::DotProduct => std::option::Option::Some(3),
                    Self::UnknownValue(u) => u.0.value(),
                }
            }

            /// Gets the enum value as a string.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the integer representation of enums.
            pub fn name(&self) -> std::option::Option<&str> {
                match self {
                    Self::Unspecified => std::option::Option::Some("DISTANCE_MEASURE_UNSPECIFIED"),
                    Self::Euclidean => std::option::Option::Some("EUCLIDEAN"),
                    Self::Cosine => std::option::Option::Some("COSINE"),
                    Self::DotProduct => std::option::Option::Some("DOT_PRODUCT"),
                    Self::UnknownValue(u) => u.0.name(),
                }
            }
        }

        impl std::default::Default for DistanceMeasure {
            fn default() -> Self {
                use std::convert::From;
                Self::from(0)
            }
        }

        impl std::fmt::Display for DistanceMeasure {
            fn fmt(
                &self,
                f: &mut std::fmt::Formatter<'_>,
            ) -> std::result::Result<(), std::fmt::Error> {
                wkt::internal::display_enum(f, self.name(), self.value())
            }
        }

        impl std::convert::From<i32> for DistanceMeasure {
            fn from(value: i32) -> Self {
                match value {
                    0 => Self::Unspecified,
                    1 => Self::Euclidean,
                    2 => Self::Cosine,
                    3 => Self::DotProduct,
                    _ => Self::UnknownValue(distance_measure::UnknownValue(
                        wkt::internal::UnknownEnumValue::Integer(value),
                    )),
                }
            }
        }

        impl std::convert::From<&str> for DistanceMeasure {
            fn from(value: &str) -> Self {
                use std::string::ToString;
                match value {
                    "DISTANCE_MEASURE_UNSPECIFIED" => Self::Unspecified,
                    "EUCLIDEAN" => Self::Euclidean,
                    "COSINE" => Self::Cosine,
                    "DOT_PRODUCT" => Self::DotProduct,
                    _ => Self::UnknownValue(distance_measure::UnknownValue(
                        wkt::internal::UnknownEnumValue::String(value.to_string()),
                    )),
                }
            }
        }

        impl serde::ser::Serialize for DistanceMeasure {
            fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
            where
                S: serde::Serializer,
            {
                match self {
                    Self::Unspecified => serializer.serialize_i32(0),
                    Self::Euclidean => serializer.serialize_i32(1),
                    Self::Cosine => serializer.serialize_i32(2),
                    Self::DotProduct => serializer.serialize_i32(3),
                    Self::UnknownValue(u) => u.0.serialize(serializer),
                }
            }
        }

        impl<'de> serde::de::Deserialize<'de> for DistanceMeasure {
            fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
            where
                D: serde::Deserializer<'de>,
            {
                deserializer.deserialize_any(wkt::internal::EnumVisitor::<DistanceMeasure>::new(
                    ".google.firestore.v1.StructuredQuery.FindNearest.DistanceMeasure",
                ))
            }
        }
    }

    /// A sort direction.
    ///
    /// # Working with unknown values
    ///
    /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
    /// additional enum variants at any time. Adding new variants is not considered
    /// a breaking change. Applications should write their code in anticipation of:
    ///
    /// - New values appearing in future releases of the client library, **and**
    /// - New values received dynamically, without application changes.
    ///
    /// Please consult the [Working with enums] section in the user guide for some
    /// guidelines.
    ///
    /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Direction {
        /// Unspecified.
        Unspecified,
        /// Ascending.
        Ascending,
        /// Descending.
        Descending,
        /// If set, the enum was initialized with an unknown value.
        ///
        /// Applications can examine the value using [Direction::value] or
        /// [Direction::name].
        UnknownValue(direction::UnknownValue),
    }

    #[doc(hidden)]
    pub mod direction {
        #[allow(unused_imports)]
        use super::*;
        #[derive(Clone, Debug, PartialEq)]
        pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
    }

    impl Direction {
        /// Gets the enum value.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the string representation of enums.
        pub fn value(&self) -> std::option::Option<i32> {
            match self {
                Self::Unspecified => std::option::Option::Some(0),
                Self::Ascending => std::option::Option::Some(1),
                Self::Descending => std::option::Option::Some(2),
                Self::UnknownValue(u) => u.0.value(),
            }
        }

        /// Gets the enum value as a string.
        ///
        /// Returns `None` if the enum contains an unknown value deserialized from
        /// the integer representation of enums.
        pub fn name(&self) -> std::option::Option<&str> {
            match self {
                Self::Unspecified => std::option::Option::Some("DIRECTION_UNSPECIFIED"),
                Self::Ascending => std::option::Option::Some("ASCENDING"),
                Self::Descending => std::option::Option::Some("DESCENDING"),
                Self::UnknownValue(u) => u.0.name(),
            }
        }
    }

    impl std::default::Default for Direction {
        fn default() -> Self {
            use std::convert::From;
            Self::from(0)
        }
    }

    impl std::fmt::Display for Direction {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
            wkt::internal::display_enum(f, self.name(), self.value())
        }
    }

    impl std::convert::From<i32> for Direction {
        fn from(value: i32) -> Self {
            match value {
                0 => Self::Unspecified,
                1 => Self::Ascending,
                2 => Self::Descending,
                _ => Self::UnknownValue(direction::UnknownValue(
                    wkt::internal::UnknownEnumValue::Integer(value),
                )),
            }
        }
    }

    impl std::convert::From<&str> for Direction {
        fn from(value: &str) -> Self {
            use std::string::ToString;
            match value {
                "DIRECTION_UNSPECIFIED" => Self::Unspecified,
                "ASCENDING" => Self::Ascending,
                "DESCENDING" => Self::Descending,
                _ => Self::UnknownValue(direction::UnknownValue(
                    wkt::internal::UnknownEnumValue::String(value.to_string()),
                )),
            }
        }
    }

    impl serde::ser::Serialize for Direction {
        fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
        where
            S: serde::Serializer,
        {
            match self {
                Self::Unspecified => serializer.serialize_i32(0),
                Self::Ascending => serializer.serialize_i32(1),
                Self::Descending => serializer.serialize_i32(2),
                Self::UnknownValue(u) => u.0.serialize(serializer),
            }
        }
    }

    impl<'de> serde::de::Deserialize<'de> for Direction {
        fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            deserializer.deserialize_any(wkt::internal::EnumVisitor::<Direction>::new(
                ".google.firestore.v1.StructuredQuery.Direction",
            ))
        }
    }
}

/// Firestore query for running an aggregation over a
/// [StructuredQuery][google.firestore.v1.StructuredQuery].
///
/// [google.firestore.v1.StructuredQuery]: crate::model::StructuredQuery
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct StructuredAggregationQuery {
    /// Optional. Series of aggregations to apply over the results of the
    /// `structured_query`.
    ///
    /// Requires:
    ///
    /// * A minimum of one and maximum of five aggregations per query.
    pub aggregations: std::vec::Vec<crate::model::structured_aggregation_query::Aggregation>,

    /// The base query to aggregate over.
    pub query_type: std::option::Option<crate::model::structured_aggregation_query::QueryType>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl StructuredAggregationQuery {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [aggregations][crate::model::StructuredAggregationQuery::aggregations].
    pub fn set_aggregations<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::structured_aggregation_query::Aggregation>,
    {
        use std::iter::Iterator;
        self.aggregations = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [query_type][crate::model::StructuredAggregationQuery::query_type].
    ///
    /// Note that all the setters affecting `query_type` are mutually
    /// exclusive.
    pub fn set_query_type<
        T: std::convert::Into<
                std::option::Option<crate::model::structured_aggregation_query::QueryType>,
            >,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.query_type = v.into();
        self
    }

    /// The value of [query_type][crate::model::StructuredAggregationQuery::query_type]
    /// if it holds a `StructuredQuery`, `None` if the field is not set or
    /// holds a different branch.
    pub fn structured_query(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::StructuredQuery>> {
        #[allow(unreachable_patterns)]
        self.query_type.as_ref().and_then(|v| match v {
            crate::model::structured_aggregation_query::QueryType::StructuredQuery(v) => {
                std::option::Option::Some(v)
            }
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [query_type][crate::model::StructuredAggregationQuery::query_type]
    /// to hold a `StructuredQuery`.
    ///
    /// Note that all the setters affecting `query_type` are
    /// mutually exclusive.
    pub fn set_structured_query<
        T: std::convert::Into<std::boxed::Box<crate::model::StructuredQuery>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.query_type = std::option::Option::Some(
            crate::model::structured_aggregation_query::QueryType::StructuredQuery(v.into()),
        );
        self
    }
}

impl wkt::message::Message for StructuredAggregationQuery {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.StructuredAggregationQuery"
    }
}

/// Defines additional types related to [StructuredAggregationQuery].
pub mod structured_aggregation_query {
    #[allow(unused_imports)]
    use super::*;

    /// Defines an aggregation that produces a single result.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct Aggregation {
        /// Optional. Optional name of the field to store the result of the
        /// aggregation into.
        ///
        /// If not provided, Firestore will pick a default name following the format
        /// `field_<incremental_id++>`. For example:
        ///
        /// ```norust
        /// AGGREGATE
        ///   COUNT_UP_TO(1) AS count_up_to_1,
        ///   COUNT_UP_TO(2),
        ///   COUNT_UP_TO(3) AS count_up_to_3,
        ///   COUNT(*)
        /// OVER (
        ///   ...
        /// );
        /// ```
        ///
        /// becomes:
        ///
        /// ```norust
        /// AGGREGATE
        ///   COUNT_UP_TO(1) AS count_up_to_1,
        ///   COUNT_UP_TO(2) AS field_1,
        ///   COUNT_UP_TO(3) AS count_up_to_3,
        ///   COUNT(*) AS field_2
        /// OVER (
        ///   ...
        /// );
        /// ```
        ///
        /// Requires:
        ///
        /// * Must be unique across all aggregation aliases.
        /// * Conform to [document field name][google.firestore.v1.Document.fields]
        ///   limitations.
        ///
        /// [google.firestore.v1.Document.fields]: crate::model::Document::fields
        pub alias: std::string::String,

        /// The type of aggregation to perform, required.
        pub operator:
            std::option::Option<crate::model::structured_aggregation_query::aggregation::Operator>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl Aggregation {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [alias][crate::model::structured_aggregation_query::Aggregation::alias].
        pub fn set_alias<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.alias = v.into();
            self
        }

        /// Sets the value of [operator][crate::model::structured_aggregation_query::Aggregation::operator].
        ///
        /// Note that all the setters affecting `operator` are mutually
        /// exclusive.
        pub fn set_operator<
            T: std::convert::Into<
                    std::option::Option<
                        crate::model::structured_aggregation_query::aggregation::Operator,
                    >,
                >,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.operator = v.into();
            self
        }

        /// The value of [operator][crate::model::structured_aggregation_query::Aggregation::operator]
        /// if it holds a `Count`, `None` if the field is not set or
        /// holds a different branch.
        pub fn count(
            &self,
        ) -> std::option::Option<
            &std::boxed::Box<crate::model::structured_aggregation_query::aggregation::Count>,
        > {
            #[allow(unreachable_patterns)]
            self.operator.as_ref().and_then(|v| match v {
                crate::model::structured_aggregation_query::aggregation::Operator::Count(v) => {
                    std::option::Option::Some(v)
                }
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [operator][crate::model::structured_aggregation_query::Aggregation::operator]
        /// to hold a `Count`.
        ///
        /// Note that all the setters affecting `operator` are
        /// mutually exclusive.
        pub fn set_count<
            T: std::convert::Into<
                    std::boxed::Box<crate::model::structured_aggregation_query::aggregation::Count>,
                >,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.operator = std::option::Option::Some(
                crate::model::structured_aggregation_query::aggregation::Operator::Count(v.into()),
            );
            self
        }

        /// The value of [operator][crate::model::structured_aggregation_query::Aggregation::operator]
        /// if it holds a `Sum`, `None` if the field is not set or
        /// holds a different branch.
        pub fn sum(
            &self,
        ) -> std::option::Option<
            &std::boxed::Box<crate::model::structured_aggregation_query::aggregation::Sum>,
        > {
            #[allow(unreachable_patterns)]
            self.operator.as_ref().and_then(|v| match v {
                crate::model::structured_aggregation_query::aggregation::Operator::Sum(v) => {
                    std::option::Option::Some(v)
                }
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [operator][crate::model::structured_aggregation_query::Aggregation::operator]
        /// to hold a `Sum`.
        ///
        /// Note that all the setters affecting `operator` are
        /// mutually exclusive.
        pub fn set_sum<
            T: std::convert::Into<
                    std::boxed::Box<crate::model::structured_aggregation_query::aggregation::Sum>,
                >,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.operator = std::option::Option::Some(
                crate::model::structured_aggregation_query::aggregation::Operator::Sum(v.into()),
            );
            self
        }

        /// The value of [operator][crate::model::structured_aggregation_query::Aggregation::operator]
        /// if it holds a `Avg`, `None` if the field is not set or
        /// holds a different branch.
        pub fn avg(
            &self,
        ) -> std::option::Option<
            &std::boxed::Box<crate::model::structured_aggregation_query::aggregation::Avg>,
        > {
            #[allow(unreachable_patterns)]
            self.operator.as_ref().and_then(|v| match v {
                crate::model::structured_aggregation_query::aggregation::Operator::Avg(v) => {
                    std::option::Option::Some(v)
                }
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [operator][crate::model::structured_aggregation_query::Aggregation::operator]
        /// to hold a `Avg`.
        ///
        /// Note that all the setters affecting `operator` are
        /// mutually exclusive.
        pub fn set_avg<
            T: std::convert::Into<
                    std::boxed::Box<crate::model::structured_aggregation_query::aggregation::Avg>,
                >,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.operator = std::option::Option::Some(
                crate::model::structured_aggregation_query::aggregation::Operator::Avg(v.into()),
            );
            self
        }
    }

    impl wkt::message::Message for Aggregation {
        fn typename() -> &'static str {
            "type.googleapis.com/google.firestore.v1.StructuredAggregationQuery.Aggregation"
        }
    }

    /// Defines additional types related to [Aggregation].
    pub mod aggregation {
        #[allow(unused_imports)]
        use super::*;

        /// Count of documents that match the query.
        ///
        /// The `COUNT(*)` aggregation function operates on the entire document
        /// so it does not require a field reference.
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct Count {
            /// Optional. Optional constraint on the maximum number of documents to
            /// count.
            ///
            /// This provides a way to set an upper bound on the number of documents
            /// to scan, limiting latency, and cost.
            ///
            /// Unspecified is interpreted as no bound.
            ///
            /// High-Level Example:
            ///
            /// ```norust
            /// AGGREGATE COUNT_UP_TO(1000) OVER ( SELECT * FROM k );
            /// ```
            ///
            /// Requires:
            ///
            /// * Must be greater than zero when present.
            pub up_to: std::option::Option<wkt::Int64Value>,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl Count {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [up_to][crate::model::structured_aggregation_query::aggregation::Count::up_to].
            pub fn set_up_to<T>(mut self, v: T) -> Self
            where
                T: std::convert::Into<wkt::Int64Value>,
            {
                self.up_to = std::option::Option::Some(v.into());
                self
            }

            /// Sets or clears the value of [up_to][crate::model::structured_aggregation_query::aggregation::Count::up_to].
            pub fn set_or_clear_up_to<T>(mut self, v: std::option::Option<T>) -> Self
            where
                T: std::convert::Into<wkt::Int64Value>,
            {
                self.up_to = v.map(|x| x.into());
                self
            }
        }

        impl wkt::message::Message for Count {
            fn typename() -> &'static str {
                "type.googleapis.com/google.firestore.v1.StructuredAggregationQuery.Aggregation.Count"
            }
        }

        /// Sum of the values of the requested field.
        ///
        /// * Only numeric values will be aggregated. All non-numeric values
        ///   including `NULL` are skipped.
        ///
        /// * If the aggregated values contain `NaN`, returns `NaN`. Infinity math
        ///   follows IEEE-754 standards.
        ///
        /// * If the aggregated value set is empty, returns 0.
        ///
        /// * Returns a 64-bit integer if all aggregated numbers are integers and the
        ///   sum result does not overflow. Otherwise, the result is returned as a
        ///   double. Note that even if all the aggregated values are integers, the
        ///   result is returned as a double if it cannot fit within a 64-bit signed
        ///   integer. When this occurs, the returned value will lose precision.
        ///
        /// * When underflow occurs, floating-point aggregation is non-deterministic.
        ///   This means that running the same query repeatedly without any changes to
        ///   the underlying values could produce slightly different results each
        ///   time. In those cases, values should be stored as integers over
        ///   floating-point numbers.
        ///
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct Sum {
            /// The field to aggregate on.
            pub field: std::option::Option<crate::model::structured_query::FieldReference>,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl Sum {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [field][crate::model::structured_aggregation_query::aggregation::Sum::field].
            pub fn set_field<T>(mut self, v: T) -> Self
            where
                T: std::convert::Into<crate::model::structured_query::FieldReference>,
            {
                self.field = std::option::Option::Some(v.into());
                self
            }

            /// Sets or clears the value of [field][crate::model::structured_aggregation_query::aggregation::Sum::field].
            pub fn set_or_clear_field<T>(mut self, v: std::option::Option<T>) -> Self
            where
                T: std::convert::Into<crate::model::structured_query::FieldReference>,
            {
                self.field = v.map(|x| x.into());
                self
            }
        }

        impl wkt::message::Message for Sum {
            fn typename() -> &'static str {
                "type.googleapis.com/google.firestore.v1.StructuredAggregationQuery.Aggregation.Sum"
            }
        }

        /// Average of the values of the requested field.
        ///
        /// * Only numeric values will be aggregated. All non-numeric values
        ///   including `NULL` are skipped.
        ///
        /// * If the aggregated values contain `NaN`, returns `NaN`. Infinity math
        ///   follows IEEE-754 standards.
        ///
        /// * If the aggregated value set is empty, returns `NULL`.
        ///
        /// * Always returns the result as a double.
        ///
        #[derive(Clone, Default, PartialEq)]
        #[non_exhaustive]
        pub struct Avg {
            /// The field to aggregate on.
            pub field: std::option::Option<crate::model::structured_query::FieldReference>,

            pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
        }

        impl Avg {
            pub fn new() -> Self {
                std::default::Default::default()
            }

            /// Sets the value of [field][crate::model::structured_aggregation_query::aggregation::Avg::field].
            pub fn set_field<T>(mut self, v: T) -> Self
            where
                T: std::convert::Into<crate::model::structured_query::FieldReference>,
            {
                self.field = std::option::Option::Some(v.into());
                self
            }

            /// Sets or clears the value of [field][crate::model::structured_aggregation_query::aggregation::Avg::field].
            pub fn set_or_clear_field<T>(mut self, v: std::option::Option<T>) -> Self
            where
                T: std::convert::Into<crate::model::structured_query::FieldReference>,
            {
                self.field = v.map(|x| x.into());
                self
            }
        }

        impl wkt::message::Message for Avg {
            fn typename() -> &'static str {
                "type.googleapis.com/google.firestore.v1.StructuredAggregationQuery.Aggregation.Avg"
            }
        }

        /// The type of aggregation to perform, required.
        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum Operator {
            /// Count aggregator.
            Count(std::boxed::Box<crate::model::structured_aggregation_query::aggregation::Count>),
            /// Sum aggregator.
            Sum(std::boxed::Box<crate::model::structured_aggregation_query::aggregation::Sum>),
            /// Average aggregator.
            Avg(std::boxed::Box<crate::model::structured_aggregation_query::aggregation::Avg>),
        }

        impl Operator {
            /// Initializes the enum to the [Count](Self::Count) branch.
            pub fn from_count(
                value: impl std::convert::Into<
                    std::boxed::Box<crate::model::structured_aggregation_query::aggregation::Count>,
                >,
            ) -> Self {
                Self::Count(value.into())
            }
            /// Initializes the enum to the [Sum](Self::Sum) branch.
            pub fn from_sum(
                value: impl std::convert::Into<
                    std::boxed::Box<crate::model::structured_aggregation_query::aggregation::Sum>,
                >,
            ) -> Self {
                Self::Sum(value.into())
            }
            /// Initializes the enum to the [Avg](Self::Avg) branch.
            pub fn from_avg(
                value: impl std::convert::Into<
                    std::boxed::Box<crate::model::structured_aggregation_query::aggregation::Avg>,
                >,
            ) -> Self {
                Self::Avg(value.into())
            }
        }
    }

    /// The base query to aggregate over.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum QueryType {
        /// Nested structured query.
        StructuredQuery(std::boxed::Box<crate::model::StructuredQuery>),
    }

    impl QueryType {
        /// Initializes the enum to the [StructuredQuery](Self::StructuredQuery) branch.
        pub fn from_structured_query(
            value: impl std::convert::Into<std::boxed::Box<crate::model::StructuredQuery>>,
        ) -> Self {
            Self::StructuredQuery(value.into())
        }
    }
}

/// A position in a query result set.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Cursor {
    /// The values that represent a position, in the order they appear in
    /// the order by clause of a query.
    ///
    /// Can contain fewer values than specified in the order by clause.
    pub values: std::vec::Vec<crate::model::Value>,

    /// If the position is just before or just after the given values, relative
    /// to the sort order defined by the query.
    pub before: bool,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Cursor {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [values][crate::model::Cursor::values].
    pub fn set_values<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::Value>,
    {
        use std::iter::Iterator;
        self.values = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [before][crate::model::Cursor::before].
    pub fn set_before<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.before = v.into();
        self
    }
}

impl wkt::message::Message for Cursor {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.Cursor"
    }
}

/// Explain options for the query.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ExplainOptions {
    /// Optional. Whether to execute this query.
    ///
    /// When false (the default), the query will be planned, returning only
    /// metrics from the planning stages.
    ///
    /// When true, the query will be planned and executed, returning the full
    /// query results along with both planning and execution stage metrics.
    pub analyze: bool,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ExplainOptions {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [analyze][crate::model::ExplainOptions::analyze].
    pub fn set_analyze<T: std::convert::Into<bool>>(mut self, v: T) -> Self {
        self.analyze = v.into();
        self
    }
}

impl wkt::message::Message for ExplainOptions {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.ExplainOptions"
    }
}

/// Explain metrics for the query.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ExplainMetrics {
    /// Planning phase information for the query.
    pub plan_summary: std::option::Option<crate::model::PlanSummary>,

    /// Aggregated stats from the execution of the query. Only present when
    /// [ExplainOptions.analyze][google.firestore.v1.ExplainOptions.analyze] is set
    /// to true.
    ///
    /// [google.firestore.v1.ExplainOptions.analyze]: crate::model::ExplainOptions::analyze
    pub execution_stats: std::option::Option<crate::model::ExecutionStats>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ExplainMetrics {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [plan_summary][crate::model::ExplainMetrics::plan_summary].
    pub fn set_plan_summary<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::PlanSummary>,
    {
        self.plan_summary = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [plan_summary][crate::model::ExplainMetrics::plan_summary].
    pub fn set_or_clear_plan_summary<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::PlanSummary>,
    {
        self.plan_summary = v.map(|x| x.into());
        self
    }

    /// Sets the value of [execution_stats][crate::model::ExplainMetrics::execution_stats].
    pub fn set_execution_stats<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::ExecutionStats>,
    {
        self.execution_stats = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [execution_stats][crate::model::ExplainMetrics::execution_stats].
    pub fn set_or_clear_execution_stats<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::ExecutionStats>,
    {
        self.execution_stats = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for ExplainMetrics {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.ExplainMetrics"
    }
}

/// Planning phase information for the query.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct PlanSummary {
    /// The indexes selected for the query. For example:
    /// [
    /// {"query_scope": "Collection", "properties": "(foo ASC, __name__ ASC)"},
    /// {"query_scope": "Collection", "properties": "(bar ASC, __name__ ASC)"}
    /// ]
    pub indexes_used: std::vec::Vec<wkt::Struct>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl PlanSummary {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [indexes_used][crate::model::PlanSummary::indexes_used].
    pub fn set_indexes_used<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<wkt::Struct>,
    {
        use std::iter::Iterator;
        self.indexes_used = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for PlanSummary {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.PlanSummary"
    }
}

/// Execution statistics for the query.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ExecutionStats {
    /// Total number of results returned, including documents, projections,
    /// aggregation results, keys.
    pub results_returned: i64,

    /// Total time to execute the query in the backend.
    pub execution_duration: std::option::Option<wkt::Duration>,

    /// Total billable read operations.
    pub read_operations: i64,

    /// Debugging statistics from the execution of the query. Note that the
    /// debugging stats are subject to change as Firestore evolves. It could
    /// include:
    /// {
    /// "indexes_entries_scanned": "1000",
    /// "documents_scanned": "20",
    /// "billing_details" : {
    /// "documents_billable": "20",
    /// "index_entries_billable": "1000",
    /// "min_query_cost": "0"
    /// }
    /// }
    pub debug_stats: std::option::Option<wkt::Struct>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ExecutionStats {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [results_returned][crate::model::ExecutionStats::results_returned].
    pub fn set_results_returned<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
        self.results_returned = v.into();
        self
    }

    /// Sets the value of [execution_duration][crate::model::ExecutionStats::execution_duration].
    pub fn set_execution_duration<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.execution_duration = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [execution_duration][crate::model::ExecutionStats::execution_duration].
    pub fn set_or_clear_execution_duration<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Duration>,
    {
        self.execution_duration = v.map(|x| x.into());
        self
    }

    /// Sets the value of [read_operations][crate::model::ExecutionStats::read_operations].
    pub fn set_read_operations<T: std::convert::Into<i64>>(mut self, v: T) -> Self {
        self.read_operations = v.into();
        self
    }

    /// Sets the value of [debug_stats][crate::model::ExecutionStats::debug_stats].
    pub fn set_debug_stats<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Struct>,
    {
        self.debug_stats = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [debug_stats][crate::model::ExecutionStats::debug_stats].
    pub fn set_or_clear_debug_stats<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Struct>,
    {
        self.debug_stats = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for ExecutionStats {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.ExecutionStats"
    }
}

/// A write on a document.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct Write {
    /// The fields to update in this write.
    ///
    /// This field can be set only when the operation is `update`.
    /// If the mask is not set for an `update` and the document exists, any
    /// existing data will be overwritten.
    /// If the mask is set and the document on the server has fields not covered by
    /// the mask, they are left unchanged.
    /// Fields referenced in the mask, but not present in the input document, are
    /// deleted from the document on the server.
    /// The field paths in this mask must not contain a reserved field name.
    pub update_mask: std::option::Option<crate::model::DocumentMask>,

    /// The transforms to perform after update.
    ///
    /// This field can be set only when the operation is `update`. If present, this
    /// write is equivalent to performing `update` and `transform` to the same
    /// document atomically and in order.
    pub update_transforms: std::vec::Vec<crate::model::document_transform::FieldTransform>,

    /// An optional precondition on the document.
    ///
    /// The write will fail if this is set and not met by the target document.
    pub current_document: std::option::Option<crate::model::Precondition>,

    /// The operation to execute.
    pub operation: std::option::Option<crate::model::write::Operation>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl Write {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [update_mask][crate::model::Write::update_mask].
    pub fn set_update_mask<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::DocumentMask>,
    {
        self.update_mask = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_mask][crate::model::Write::update_mask].
    pub fn set_or_clear_update_mask<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::DocumentMask>,
    {
        self.update_mask = v.map(|x| x.into());
        self
    }

    /// Sets the value of [update_transforms][crate::model::Write::update_transforms].
    pub fn set_update_transforms<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::document_transform::FieldTransform>,
    {
        use std::iter::Iterator;
        self.update_transforms = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [current_document][crate::model::Write::current_document].
    pub fn set_current_document<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Precondition>,
    {
        self.current_document = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [current_document][crate::model::Write::current_document].
    pub fn set_or_clear_current_document<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Precondition>,
    {
        self.current_document = v.map(|x| x.into());
        self
    }

    /// Sets the value of [operation][crate::model::Write::operation].
    ///
    /// Note that all the setters affecting `operation` are mutually
    /// exclusive.
    pub fn set_operation<
        T: std::convert::Into<std::option::Option<crate::model::write::Operation>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.operation = v.into();
        self
    }

    /// The value of [operation][crate::model::Write::operation]
    /// if it holds a `Update`, `None` if the field is not set or
    /// holds a different branch.
    pub fn update(&self) -> std::option::Option<&std::boxed::Box<crate::model::Document>> {
        #[allow(unreachable_patterns)]
        self.operation.as_ref().and_then(|v| match v {
            crate::model::write::Operation::Update(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [operation][crate::model::Write::operation]
    /// to hold a `Update`.
    ///
    /// Note that all the setters affecting `operation` are
    /// mutually exclusive.
    pub fn set_update<T: std::convert::Into<std::boxed::Box<crate::model::Document>>>(
        mut self,
        v: T,
    ) -> Self {
        self.operation =
            std::option::Option::Some(crate::model::write::Operation::Update(v.into()));
        self
    }

    /// The value of [operation][crate::model::Write::operation]
    /// if it holds a `Delete`, `None` if the field is not set or
    /// holds a different branch.
    pub fn delete(&self) -> std::option::Option<&std::string::String> {
        #[allow(unreachable_patterns)]
        self.operation.as_ref().and_then(|v| match v {
            crate::model::write::Operation::Delete(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [operation][crate::model::Write::operation]
    /// to hold a `Delete`.
    ///
    /// Note that all the setters affecting `operation` are
    /// mutually exclusive.
    pub fn set_delete<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.operation =
            std::option::Option::Some(crate::model::write::Operation::Delete(v.into()));
        self
    }

    /// The value of [operation][crate::model::Write::operation]
    /// if it holds a `Transform`, `None` if the field is not set or
    /// holds a different branch.
    pub fn transform(
        &self,
    ) -> std::option::Option<&std::boxed::Box<crate::model::DocumentTransform>> {
        #[allow(unreachable_patterns)]
        self.operation.as_ref().and_then(|v| match v {
            crate::model::write::Operation::Transform(v) => std::option::Option::Some(v),
            _ => std::option::Option::None,
        })
    }

    /// Sets the value of [operation][crate::model::Write::operation]
    /// to hold a `Transform`.
    ///
    /// Note that all the setters affecting `operation` are
    /// mutually exclusive.
    pub fn set_transform<
        T: std::convert::Into<std::boxed::Box<crate::model::DocumentTransform>>,
    >(
        mut self,
        v: T,
    ) -> Self {
        self.operation =
            std::option::Option::Some(crate::model::write::Operation::Transform(v.into()));
        self
    }
}

impl wkt::message::Message for Write {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.Write"
    }
}

/// Defines additional types related to [Write].
pub mod write {
    #[allow(unused_imports)]
    use super::*;

    /// The operation to execute.
    #[derive(Clone, Debug, PartialEq)]
    #[non_exhaustive]
    pub enum Operation {
        /// A document to write.
        Update(std::boxed::Box<crate::model::Document>),
        /// A document name to delete. In the format:
        /// `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
        Delete(std::string::String),
        /// Applies a transformation to a document.
        Transform(std::boxed::Box<crate::model::DocumentTransform>),
    }

    impl Operation {
        /// Initializes the enum to the [Update](Self::Update) branch.
        pub fn from_update(
            value: impl std::convert::Into<std::boxed::Box<crate::model::Document>>,
        ) -> Self {
            Self::Update(value.into())
        }
        /// Initializes the enum to the [Delete](Self::Delete) branch.
        pub fn from_delete(value: impl std::convert::Into<std::string::String>) -> Self {
            Self::Delete(value.into())
        }
        /// Initializes the enum to the [Transform](Self::Transform) branch.
        pub fn from_transform(
            value: impl std::convert::Into<std::boxed::Box<crate::model::DocumentTransform>>,
        ) -> Self {
            Self::Transform(value.into())
        }
    }
}

/// A transformation of a document.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct DocumentTransform {
    /// The name of the document to transform.
    pub document: std::string::String,

    /// The list of transformations to apply to the fields of the document, in
    /// order.
    /// This must not be empty.
    pub field_transforms: std::vec::Vec<crate::model::document_transform::FieldTransform>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl DocumentTransform {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [document][crate::model::DocumentTransform::document].
    pub fn set_document<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.document = v.into();
        self
    }

    /// Sets the value of [field_transforms][crate::model::DocumentTransform::field_transforms].
    pub fn set_field_transforms<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::document_transform::FieldTransform>,
    {
        use std::iter::Iterator;
        self.field_transforms = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for DocumentTransform {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.DocumentTransform"
    }
}

/// Defines additional types related to [DocumentTransform].
pub mod document_transform {
    #[allow(unused_imports)]
    use super::*;

    /// A transformation of a field of the document.
    #[derive(Clone, Default, PartialEq)]
    #[non_exhaustive]
    pub struct FieldTransform {
        /// The path of the field. See
        /// [Document.fields][google.firestore.v1.Document.fields] for the field path
        /// syntax reference.
        ///
        /// [google.firestore.v1.Document.fields]: crate::model::Document::fields
        pub field_path: std::string::String,

        /// The transformation to apply on the field.
        pub transform_type:
            std::option::Option<crate::model::document_transform::field_transform::TransformType>,

        pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
    }

    impl FieldTransform {
        pub fn new() -> Self {
            std::default::Default::default()
        }

        /// Sets the value of [field_path][crate::model::document_transform::FieldTransform::field_path].
        pub fn set_field_path<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
            self.field_path = v.into();
            self
        }

        /// Sets the value of [transform_type][crate::model::document_transform::FieldTransform::transform_type].
        ///
        /// Note that all the setters affecting `transform_type` are mutually
        /// exclusive.
        pub fn set_transform_type<
            T: std::convert::Into<
                    std::option::Option<
                        crate::model::document_transform::field_transform::TransformType,
                    >,
                >,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.transform_type = v.into();
            self
        }

        /// The value of [transform_type][crate::model::document_transform::FieldTransform::transform_type]
        /// if it holds a `SetToServerValue`, `None` if the field is not set or
        /// holds a different branch.
        pub fn set_to_server_value(
            &self,
        ) -> std::option::Option<&crate::model::document_transform::field_transform::ServerValue>
        {
            #[allow(unreachable_patterns)]
            self.transform_type.as_ref().and_then(|v| match v {
                crate::model::document_transform::field_transform::TransformType::SetToServerValue(v) => std::option::Option::Some(v),
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [transform_type][crate::model::document_transform::FieldTransform::transform_type]
        /// to hold a `SetToServerValue`.
        ///
        /// Note that all the setters affecting `transform_type` are
        /// mutually exclusive.
        pub fn set_set_to_server_value<
            T: std::convert::Into<crate::model::document_transform::field_transform::ServerValue>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.transform_type = std::option::Option::Some(
                crate::model::document_transform::field_transform::TransformType::SetToServerValue(
                    v.into(),
                ),
            );
            self
        }

        /// The value of [transform_type][crate::model::document_transform::FieldTransform::transform_type]
        /// if it holds a `Increment`, `None` if the field is not set or
        /// holds a different branch.
        pub fn increment(&self) -> std::option::Option<&std::boxed::Box<crate::model::Value>> {
            #[allow(unreachable_patterns)]
            self.transform_type.as_ref().and_then(|v| match v {
                crate::model::document_transform::field_transform::TransformType::Increment(v) => {
                    std::option::Option::Some(v)
                }
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [transform_type][crate::model::document_transform::FieldTransform::transform_type]
        /// to hold a `Increment`.
        ///
        /// Note that all the setters affecting `transform_type` are
        /// mutually exclusive.
        pub fn set_increment<T: std::convert::Into<std::boxed::Box<crate::model::Value>>>(
            mut self,
            v: T,
        ) -> Self {
            self.transform_type = std::option::Option::Some(
                crate::model::document_transform::field_transform::TransformType::Increment(
                    v.into(),
                ),
            );
            self
        }

        /// The value of [transform_type][crate::model::document_transform::FieldTransform::transform_type]
        /// if it holds a `Maximum`, `None` if the field is not set or
        /// holds a different branch.
        pub fn maximum(&self) -> std::option::Option<&std::boxed::Box<crate::model::Value>> {
            #[allow(unreachable_patterns)]
            self.transform_type.as_ref().and_then(|v| match v {
                crate::model::document_transform::field_transform::TransformType::Maximum(v) => {
                    std::option::Option::Some(v)
                }
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [transform_type][crate::model::document_transform::FieldTransform::transform_type]
        /// to hold a `Maximum`.
        ///
        /// Note that all the setters affecting `transform_type` are
        /// mutually exclusive.
        pub fn set_maximum<T: std::convert::Into<std::boxed::Box<crate::model::Value>>>(
            mut self,
            v: T,
        ) -> Self {
            self.transform_type = std::option::Option::Some(
                crate::model::document_transform::field_transform::TransformType::Maximum(v.into()),
            );
            self
        }

        /// The value of [transform_type][crate::model::document_transform::FieldTransform::transform_type]
        /// if it holds a `Minimum`, `None` if the field is not set or
        /// holds a different branch.
        pub fn minimum(&self) -> std::option::Option<&std::boxed::Box<crate::model::Value>> {
            #[allow(unreachable_patterns)]
            self.transform_type.as_ref().and_then(|v| match v {
                crate::model::document_transform::field_transform::TransformType::Minimum(v) => {
                    std::option::Option::Some(v)
                }
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [transform_type][crate::model::document_transform::FieldTransform::transform_type]
        /// to hold a `Minimum`.
        ///
        /// Note that all the setters affecting `transform_type` are
        /// mutually exclusive.
        pub fn set_minimum<T: std::convert::Into<std::boxed::Box<crate::model::Value>>>(
            mut self,
            v: T,
        ) -> Self {
            self.transform_type = std::option::Option::Some(
                crate::model::document_transform::field_transform::TransformType::Minimum(v.into()),
            );
            self
        }

        /// The value of [transform_type][crate::model::document_transform::FieldTransform::transform_type]
        /// if it holds a `AppendMissingElements`, `None` if the field is not set or
        /// holds a different branch.
        pub fn append_missing_elements(
            &self,
        ) -> std::option::Option<&std::boxed::Box<crate::model::ArrayValue>> {
            #[allow(unreachable_patterns)]
            self.transform_type.as_ref().and_then(|v| match v {
                crate::model::document_transform::field_transform::TransformType::AppendMissingElements(v) => std::option::Option::Some(v),
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [transform_type][crate::model::document_transform::FieldTransform::transform_type]
        /// to hold a `AppendMissingElements`.
        ///
        /// Note that all the setters affecting `transform_type` are
        /// mutually exclusive.
        pub fn set_append_missing_elements<
            T: std::convert::Into<std::boxed::Box<crate::model::ArrayValue>>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.transform_type = std::option::Option::Some(
                crate::model::document_transform::field_transform::TransformType::AppendMissingElements(
                    v.into()
                )
            );
            self
        }

        /// The value of [transform_type][crate::model::document_transform::FieldTransform::transform_type]
        /// if it holds a `RemoveAllFromArray`, `None` if the field is not set or
        /// holds a different branch.
        pub fn remove_all_from_array(
            &self,
        ) -> std::option::Option<&std::boxed::Box<crate::model::ArrayValue>> {
            #[allow(unreachable_patterns)]
            self.transform_type.as_ref().and_then(|v| match v {
                crate::model::document_transform::field_transform::TransformType::RemoveAllFromArray(v) => std::option::Option::Some(v),
                _ => std::option::Option::None,
            })
        }

        /// Sets the value of [transform_type][crate::model::document_transform::FieldTransform::transform_type]
        /// to hold a `RemoveAllFromArray`.
        ///
        /// Note that all the setters affecting `transform_type` are
        /// mutually exclusive.
        pub fn set_remove_all_from_array<
            T: std::convert::Into<std::boxed::Box<crate::model::ArrayValue>>,
        >(
            mut self,
            v: T,
        ) -> Self {
            self.transform_type = std::option::Option::Some(
                crate::model::document_transform::field_transform::TransformType::RemoveAllFromArray(
                    v.into()
                )
            );
            self
        }
    }

    impl wkt::message::Message for FieldTransform {
        fn typename() -> &'static str {
            "type.googleapis.com/google.firestore.v1.DocumentTransform.FieldTransform"
        }
    }

    /// Defines additional types related to [FieldTransform].
    pub mod field_transform {
        #[allow(unused_imports)]
        use super::*;

        /// A value that is calculated by the server.
        ///
        /// # Working with unknown values
        ///
        /// This enum is defined as `#[non_exhaustive]` because Google Cloud may add
        /// additional enum variants at any time. Adding new variants is not considered
        /// a breaking change. Applications should write their code in anticipation of:
        ///
        /// - New values appearing in future releases of the client library, **and**
        /// - New values received dynamically, without application changes.
        ///
        /// Please consult the [Working with enums] section in the user guide for some
        /// guidelines.
        ///
        /// [Working with enums]: https://google-cloud-rust.github.io/working_with_enums.html
        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum ServerValue {
            /// Unspecified. This value must not be used.
            Unspecified,
            /// The time at which the server processed the request, with millisecond
            /// precision. If used on multiple fields (same or different documents) in
            /// a transaction, all the fields will get the same server timestamp.
            RequestTime,
            /// If set, the enum was initialized with an unknown value.
            ///
            /// Applications can examine the value using [ServerValue::value] or
            /// [ServerValue::name].
            UnknownValue(server_value::UnknownValue),
        }

        #[doc(hidden)]
        pub mod server_value {
            #[allow(unused_imports)]
            use super::*;
            #[derive(Clone, Debug, PartialEq)]
            pub struct UnknownValue(pub(crate) wkt::internal::UnknownEnumValue);
        }

        impl ServerValue {
            /// Gets the enum value.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the string representation of enums.
            pub fn value(&self) -> std::option::Option<i32> {
                match self {
                    Self::Unspecified => std::option::Option::Some(0),
                    Self::RequestTime => std::option::Option::Some(1),
                    Self::UnknownValue(u) => u.0.value(),
                }
            }

            /// Gets the enum value as a string.
            ///
            /// Returns `None` if the enum contains an unknown value deserialized from
            /// the integer representation of enums.
            pub fn name(&self) -> std::option::Option<&str> {
                match self {
                    Self::Unspecified => std::option::Option::Some("SERVER_VALUE_UNSPECIFIED"),
                    Self::RequestTime => std::option::Option::Some("REQUEST_TIME"),
                    Self::UnknownValue(u) => u.0.name(),
                }
            }
        }

        impl std::default::Default for ServerValue {
            fn default() -> Self {
                use std::convert::From;
                Self::from(0)
            }
        }

        impl std::fmt::Display for ServerValue {
            fn fmt(
                &self,
                f: &mut std::fmt::Formatter<'_>,
            ) -> std::result::Result<(), std::fmt::Error> {
                wkt::internal::display_enum(f, self.name(), self.value())
            }
        }

        impl std::convert::From<i32> for ServerValue {
            fn from(value: i32) -> Self {
                match value {
                    0 => Self::Unspecified,
                    1 => Self::RequestTime,
                    _ => Self::UnknownValue(server_value::UnknownValue(
                        wkt::internal::UnknownEnumValue::Integer(value),
                    )),
                }
            }
        }

        impl std::convert::From<&str> for ServerValue {
            fn from(value: &str) -> Self {
                use std::string::ToString;
                match value {
                    "SERVER_VALUE_UNSPECIFIED" => Self::Unspecified,
                    "REQUEST_TIME" => Self::RequestTime,
                    _ => Self::UnknownValue(server_value::UnknownValue(
                        wkt::internal::UnknownEnumValue::String(value.to_string()),
                    )),
                }
            }
        }

        impl serde::ser::Serialize for ServerValue {
            fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
            where
                S: serde::Serializer,
            {
                match self {
                    Self::Unspecified => serializer.serialize_i32(0),
                    Self::RequestTime => serializer.serialize_i32(1),
                    Self::UnknownValue(u) => u.0.serialize(serializer),
                }
            }
        }

        impl<'de> serde::de::Deserialize<'de> for ServerValue {
            fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
            where
                D: serde::Deserializer<'de>,
            {
                deserializer.deserialize_any(wkt::internal::EnumVisitor::<ServerValue>::new(
                    ".google.firestore.v1.DocumentTransform.FieldTransform.ServerValue",
                ))
            }
        }

        /// The transformation to apply on the field.
        #[derive(Clone, Debug, PartialEq)]
        #[non_exhaustive]
        pub enum TransformType {
            /// Sets the field to the given server value.
            SetToServerValue(crate::model::document_transform::field_transform::ServerValue),
            /// Adds the given value to the field's current value.
            ///
            /// This must be an integer or a double value.
            /// If the field is not an integer or double, or if the field does not yet
            /// exist, the transformation will set the field to the given value.
            /// If either of the given value or the current field value are doubles,
            /// both values will be interpreted as doubles. Double arithmetic and
            /// representation of double values follow IEEE 754 semantics.
            /// If there is positive/negative integer overflow, the field is resolved
            /// to the largest magnitude positive/negative integer.
            Increment(std::boxed::Box<crate::model::Value>),
            /// Sets the field to the maximum of its current value and the given value.
            ///
            /// This must be an integer or a double value.
            /// If the field is not an integer or double, or if the field does not yet
            /// exist, the transformation will set the field to the given value.
            /// If a maximum operation is applied where the field and the input value
            /// are of mixed types (that is - one is an integer and one is a double)
            /// the field takes on the type of the larger operand. If the operands are
            /// equivalent (e.g. 3 and 3.0), the field does not change.
            /// 0, 0.0, and -0.0 are all zero. The maximum of a zero stored value and
            /// zero input value is always the stored value.
            /// The maximum of any numeric value x and NaN is NaN.
            Maximum(std::boxed::Box<crate::model::Value>),
            /// Sets the field to the minimum of its current value and the given value.
            ///
            /// This must be an integer or a double value.
            /// If the field is not an integer or double, or if the field does not yet
            /// exist, the transformation will set the field to the input value.
            /// If a minimum operation is applied where the field and the input value
            /// are of mixed types (that is - one is an integer and one is a double)
            /// the field takes on the type of the smaller operand. If the operands are
            /// equivalent (e.g. 3 and 3.0), the field does not change.
            /// 0, 0.0, and -0.0 are all zero. The minimum of a zero stored value and
            /// zero input value is always the stored value.
            /// The minimum of any numeric value x and NaN is NaN.
            Minimum(std::boxed::Box<crate::model::Value>),
            /// Append the given elements in order if they are not already present in
            /// the current field value.
            /// If the field is not an array, or if the field does not yet exist, it is
            /// first set to the empty array.
            ///
            /// Equivalent numbers of different types (e.g. 3L and 3.0) are
            /// considered equal when checking if a value is missing.
            /// NaN is equal to NaN, and Null is equal to Null.
            /// If the input contains multiple equivalent values, only the first will
            /// be considered.
            ///
            /// The corresponding transform_result will be the null value.
            AppendMissingElements(std::boxed::Box<crate::model::ArrayValue>),
            /// Remove all of the given elements from the array in the field.
            /// If the field is not an array, or if the field does not yet exist, it is
            /// set to the empty array.
            ///
            /// Equivalent numbers of the different types (e.g. 3L and 3.0) are
            /// considered equal when deciding whether an element should be removed.
            /// NaN is equal to NaN, and Null is equal to Null.
            /// This will remove all equivalent values if there are duplicates.
            ///
            /// The corresponding transform_result will be the null value.
            RemoveAllFromArray(std::boxed::Box<crate::model::ArrayValue>),
        }

        impl TransformType {
            /// Initializes the enum to the [SetToServerValue](Self::SetToServerValue) branch.
            pub fn from_set_to_server_value(
                value: impl std::convert::Into<
                    crate::model::document_transform::field_transform::ServerValue,
                >,
            ) -> Self {
                Self::SetToServerValue(value.into())
            }
            /// Initializes the enum to the [Increment](Self::Increment) branch.
            pub fn from_increment(
                value: impl std::convert::Into<std::boxed::Box<crate::model::Value>>,
            ) -> Self {
                Self::Increment(value.into())
            }
            /// Initializes the enum to the [Maximum](Self::Maximum) branch.
            pub fn from_maximum(
                value: impl std::convert::Into<std::boxed::Box<crate::model::Value>>,
            ) -> Self {
                Self::Maximum(value.into())
            }
            /// Initializes the enum to the [Minimum](Self::Minimum) branch.
            pub fn from_minimum(
                value: impl std::convert::Into<std::boxed::Box<crate::model::Value>>,
            ) -> Self {
                Self::Minimum(value.into())
            }
            /// Initializes the enum to the [AppendMissingElements](Self::AppendMissingElements) branch.
            pub fn from_append_missing_elements(
                value: impl std::convert::Into<std::boxed::Box<crate::model::ArrayValue>>,
            ) -> Self {
                Self::AppendMissingElements(value.into())
            }
            /// Initializes the enum to the [RemoveAllFromArray](Self::RemoveAllFromArray) branch.
            pub fn from_remove_all_from_array(
                value: impl std::convert::Into<std::boxed::Box<crate::model::ArrayValue>>,
            ) -> Self {
                Self::RemoveAllFromArray(value.into())
            }
        }
    }
}

/// The result of applying a write.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct WriteResult {
    /// The last update time of the document after applying the write. Not set
    /// after a `delete`.
    ///
    /// If the write did not actually change the document, this will be the
    /// previous update_time.
    pub update_time: std::option::Option<wkt::Timestamp>,

    /// The results of applying each
    /// [DocumentTransform.FieldTransform][google.firestore.v1.DocumentTransform.FieldTransform],
    /// in the same order.
    ///
    /// [google.firestore.v1.DocumentTransform.FieldTransform]: crate::model::document_transform::FieldTransform
    pub transform_results: std::vec::Vec<crate::model::Value>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl WriteResult {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [update_time][crate::model::WriteResult::update_time].
    pub fn set_update_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.update_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [update_time][crate::model::WriteResult::update_time].
    pub fn set_or_clear_update_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.update_time = v.map(|x| x.into());
        self
    }

    /// Sets the value of [transform_results][crate::model::WriteResult::transform_results].
    pub fn set_transform_results<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<crate::model::Value>,
    {
        use std::iter::Iterator;
        self.transform_results = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for WriteResult {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.WriteResult"
    }
}

/// A [Document][google.firestore.v1.Document] has changed.
///
/// May be the result of multiple [writes][google.firestore.v1.Write], including
/// deletes, that ultimately resulted in a new value for the
/// [Document][google.firestore.v1.Document].
///
/// Multiple [DocumentChange][google.firestore.v1.DocumentChange] messages may be
/// returned for the same logical change, if multiple targets are affected.
///
/// [google.firestore.v1.Document]: crate::model::Document
/// [google.firestore.v1.DocumentChange]: crate::model::DocumentChange
/// [google.firestore.v1.Write]: crate::model::Write
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct DocumentChange {
    /// The new state of the [Document][google.firestore.v1.Document].
    ///
    /// If `mask` is set, contains only fields that were updated or added.
    ///
    /// [google.firestore.v1.Document]: crate::model::Document
    pub document: std::option::Option<crate::model::Document>,

    /// A set of target IDs of targets that match this document.
    pub target_ids: std::vec::Vec<i32>,

    /// A set of target IDs for targets that no longer match this document.
    pub removed_target_ids: std::vec::Vec<i32>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl DocumentChange {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [document][crate::model::DocumentChange::document].
    pub fn set_document<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::Document>,
    {
        self.document = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [document][crate::model::DocumentChange::document].
    pub fn set_or_clear_document<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::Document>,
    {
        self.document = v.map(|x| x.into());
        self
    }

    /// Sets the value of [target_ids][crate::model::DocumentChange::target_ids].
    pub fn set_target_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<i32>,
    {
        use std::iter::Iterator;
        self.target_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [removed_target_ids][crate::model::DocumentChange::removed_target_ids].
    pub fn set_removed_target_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<i32>,
    {
        use std::iter::Iterator;
        self.removed_target_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }
}

impl wkt::message::Message for DocumentChange {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.DocumentChange"
    }
}

/// A [Document][google.firestore.v1.Document] has been deleted.
///
/// May be the result of multiple [writes][google.firestore.v1.Write], including
/// updates, the last of which deleted the
/// [Document][google.firestore.v1.Document].
///
/// Multiple [DocumentDelete][google.firestore.v1.DocumentDelete] messages may be
/// returned for the same logical delete, if multiple targets are affected.
///
/// [google.firestore.v1.Document]: crate::model::Document
/// [google.firestore.v1.DocumentDelete]: crate::model::DocumentDelete
/// [google.firestore.v1.Write]: crate::model::Write
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct DocumentDelete {
    /// The resource name of the [Document][google.firestore.v1.Document] that was
    /// deleted.
    ///
    /// [google.firestore.v1.Document]: crate::model::Document
    pub document: std::string::String,

    /// A set of target IDs for targets that previously matched this entity.
    pub removed_target_ids: std::vec::Vec<i32>,

    /// The read timestamp at which the delete was observed.
    ///
    /// Greater or equal to the `commit_time` of the delete.
    pub read_time: std::option::Option<wkt::Timestamp>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl DocumentDelete {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [document][crate::model::DocumentDelete::document].
    pub fn set_document<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.document = v.into();
        self
    }

    /// Sets the value of [removed_target_ids][crate::model::DocumentDelete::removed_target_ids].
    pub fn set_removed_target_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<i32>,
    {
        use std::iter::Iterator;
        self.removed_target_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [read_time][crate::model::DocumentDelete::read_time].
    pub fn set_read_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.read_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [read_time][crate::model::DocumentDelete::read_time].
    pub fn set_or_clear_read_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.read_time = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for DocumentDelete {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.DocumentDelete"
    }
}

/// A [Document][google.firestore.v1.Document] has been removed from the view of
/// the targets.
///
/// Sent if the document is no longer relevant to a target and is out of view.
/// Can be sent instead of a DocumentDelete or a DocumentChange if the server
/// can not send the new value of the document.
///
/// Multiple [DocumentRemove][google.firestore.v1.DocumentRemove] messages may be
/// returned for the same logical write or delete, if multiple targets are
/// affected.
///
/// [google.firestore.v1.Document]: crate::model::Document
/// [google.firestore.v1.DocumentRemove]: crate::model::DocumentRemove
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct DocumentRemove {
    /// The resource name of the [Document][google.firestore.v1.Document] that has
    /// gone out of view.
    ///
    /// [google.firestore.v1.Document]: crate::model::Document
    pub document: std::string::String,

    /// A set of target IDs for targets that previously matched this document.
    pub removed_target_ids: std::vec::Vec<i32>,

    /// The read timestamp at which the remove was observed.
    ///
    /// Greater or equal to the `commit_time` of the change/delete/remove.
    pub read_time: std::option::Option<wkt::Timestamp>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl DocumentRemove {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [document][crate::model::DocumentRemove::document].
    pub fn set_document<T: std::convert::Into<std::string::String>>(mut self, v: T) -> Self {
        self.document = v.into();
        self
    }

    /// Sets the value of [removed_target_ids][crate::model::DocumentRemove::removed_target_ids].
    pub fn set_removed_target_ids<T, V>(mut self, v: T) -> Self
    where
        T: std::iter::IntoIterator<Item = V>,
        V: std::convert::Into<i32>,
    {
        use std::iter::Iterator;
        self.removed_target_ids = v.into_iter().map(|i| i.into()).collect();
        self
    }

    /// Sets the value of [read_time][crate::model::DocumentRemove::read_time].
    pub fn set_read_time<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.read_time = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [read_time][crate::model::DocumentRemove::read_time].
    pub fn set_or_clear_read_time<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<wkt::Timestamp>,
    {
        self.read_time = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for DocumentRemove {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.DocumentRemove"
    }
}

/// A digest of all the documents that match a given target.
#[derive(Clone, Default, PartialEq)]
#[non_exhaustive]
pub struct ExistenceFilter {
    /// The target ID to which this filter applies.
    pub target_id: i32,

    /// The total count of documents that match
    /// [target_id][google.firestore.v1.ExistenceFilter.target_id].
    ///
    /// If different from the count of documents in the client that match, the
    /// client must manually determine which documents no longer match the target.
    ///
    /// The client can use the `unchanged_names` bloom filter to assist with
    /// this determination by testing ALL the document names against the filter;
    /// if the document name is NOT in the filter, it means the document no
    /// longer matches the target.
    ///
    /// [google.firestore.v1.ExistenceFilter.target_id]: crate::model::ExistenceFilter::target_id
    pub count: i32,

    /// A bloom filter that, despite its name, contains the UTF-8 byte encodings of
    /// the resource names of ALL the documents that match
    /// [target_id][google.firestore.v1.ExistenceFilter.target_id], in the form
    /// `projects/{project_id}/databases/{database_id}/documents/{document_path}`.
    ///
    /// This bloom filter may be omitted at the server's discretion, such as if it
    /// is deemed that the client will not make use of it or if it is too
    /// computationally expensive to calculate or transmit. Clients must gracefully
    /// handle this field being absent by falling back to the logic used before
    /// this field existed; that is, re-add the target without a resume token to
    /// figure out which documents in the client's cache are out of sync.
    ///
    /// [google.firestore.v1.ExistenceFilter.target_id]: crate::model::ExistenceFilter::target_id
    pub unchanged_names: std::option::Option<crate::model::BloomFilter>,

    pub(crate) _unknown_fields: serde_json::Map<std::string::String, serde_json::Value>,
}

impl ExistenceFilter {
    pub fn new() -> Self {
        std::default::Default::default()
    }

    /// Sets the value of [target_id][crate::model::ExistenceFilter::target_id].
    pub fn set_target_id<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.target_id = v.into();
        self
    }

    /// Sets the value of [count][crate::model::ExistenceFilter::count].
    pub fn set_count<T: std::convert::Into<i32>>(mut self, v: T) -> Self {
        self.count = v.into();
        self
    }

    /// Sets the value of [unchanged_names][crate::model::ExistenceFilter::unchanged_names].
    pub fn set_unchanged_names<T>(mut self, v: T) -> Self
    where
        T: std::convert::Into<crate::model::BloomFilter>,
    {
        self.unchanged_names = std::option::Option::Some(v.into());
        self
    }

    /// Sets or clears the value of [unchanged_names][crate::model::ExistenceFilter::unchanged_names].
    pub fn set_or_clear_unchanged_names<T>(mut self, v: std::option::Option<T>) -> Self
    where
        T: std::convert::Into<crate::model::BloomFilter>,
    {
        self.unchanged_names = v.map(|x| x.into());
        self
    }
}

impl wkt::message::Message for ExistenceFilter {
    fn typename() -> &'static str {
        "type.googleapis.com/google.firestore.v1.ExistenceFilter"
    }
}
